diff -Naur kernel.orig/linux24/Documentation/Configure.help kernel/linux24/Documentation/Configure.help
--- kernel.orig/linux24/Documentation/Configure.help	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/Documentation/Configure.help	Fri Jun 28 20:57:45 2002
@@ -18942,6 +18942,16 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
+Kernel Hook Support
+CONFIG_HOOK
+  The Kernel Hooks Interface is a generalised facility for placing hooks in
+  arbitrary kernel locations. A hook is a location in the kernel that
+  calls out of the kernel to a kernel module routine - a hook exit routine.
+  Read Documentation/hook/HOWTO for more details.
+
+  This is required for enabling IBM Dynamic Probes. If you need Dynamic Probes
+  you have to say Y or M. If in doubt, say N.
+
 ISDN support
 CONFIG_ISDN
   ISDN ("Integrated Services Digital Networks", called RNIS in France)
diff -Naur kernel.orig/linux24/Documentation/hook/HOWTO kernel/linux24/Documentation/hook/HOWTO
--- kernel.orig/linux24/Documentation/hook/HOWTO	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/Documentation/hook/HOWTO	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,431 @@
+How to use Kernel Hooks?
+
+Date: 20th September 2001
+
+Version: 1.3
+
+Author: Richard J Moore, richardj_moore@uk.ibm.com, 
+	Vamsi Krishna S., vamsi_krishna@in.ibm.com
+	Linux Technology Centre, IBM Corp.
+
+Copyright 2000 IBM Corporation
+Copyright 2000 IBM UK Ltd
+
+
+Introduction:
+------------
+
+The Kernel Hooks Interface is a generalised facility for placing hooks in 
+arbitrary kernel locations. A hook is a location in the kernel
+that calls out of the kernel to a kernel module routine - a hook exit routine.
+It enables many kernel enhancements, which are otherwise self-contained, to
+become loadable kernel modules and retain a substantial degree of independence
+from the kernel source. This affords advantages for maintenance and
+co-existence with other kernel enhancements. 
+
+Hooks are implemented as fast and slim-line insertions to kernel space code.
+When not active that have practically no overhead to the kernel. They are in
+essence a conditional jmp to the exit dispatching code. 
+
+There are two hook optimizations employed in gkhi, one of which is optional - the
+exclusive hook; the other - the arch-hook - is dependent on the IA32 architecture
+and always used in that environment.
+
+The exclusive hook eliminates some of the generalised processing associated with
+dispatching multiple exits. This can be used where it is known that only one 
+exit would ever register to use a hook. Exclusive hooks are coded as 
+EXCLUSIVE_HOOK, EXCLUSIVE_HOOK_RET etc. You have to use the macro
+DECLARE_EXCLUSIVE_HOOK_HEAD to declare the exclusive hook.
+
+The arch-hook optimization uses architecturally dependent features. We have 
+provided an implementation for IA32, though could be ported to other 
+architectures without difficulty. The code for the IA32 implementation may 
+be found in include/asm-i386/hook.h. This optimization is always used under IA32. 
+It is implemented by:
+ 
+  1. moving the hook exit dispatching code to a separate section to minimise the
+     icache footprint of the hook code. (This should be applicable
+     to all architectures.)
+  2. changing the test for the conditional jmp to be dependent on a register variable
+     which set by moving a literal constant into the register.
+  3. modifying the literal value in the MOV instruction to activate and deactivate the
+     hook.
+ 
+These actions both minimise the cache hit and the number of instructions required to
+test for an inactive hook.
+
+There is another type of hooks: generic hooks. These are slower than the
+arch-optimized hooks, but they generate no symbols at hook locations and
+could be used to place hooks even in inline functions. Use the macros
+DECLARE_GENERIC_HOOK_HEAD and GENERIC_HOOK etc. to define generic hooks.
+
+The hook interface allows multiple kernel modules to register their exits for
+a given hook, in order to receive control at that given hook location. Multiple
+hooks may be defined within the kernel and a single kernel module may register
+exits to use multiple hooks.
+
+When hook exits register they may specify co-existence criteria, that is
+whether they can co-exist with other exist for the same hook and their
+dispatching priority.
+
+Hooks may be placed in kernel modules as well as the kernel itself.
+
+A hook exit receives control as if called from the code in which the hook is
+placed. Parameters may be passed to a hook exit and may be modified by an
+exit (subject to being declared for that purpose). The exit may return a
+non-zero result to stop other exits from being dispatched.
+
+There are two type of hook:
+
+	normal.
+	conditional return.
+
+With normal hooks, control returns to the hooked code after any exits are
+dispatched.
+
+With conditional return hooks, an exit may optionally specify that the routine
+in which the hook is coded must return when the exit returns.
+
+Exits are made callable in a two-stage process:
+
+1) Registration - this is used to make the exit known to the hook interface
+and to perform some validation. 
+
+2) Arming - this is used to make a set of exits callable. The arming operation
+is atomic as far as kernel processing is concerned.
+
+These operations may be reversed using disarming and de-registration functions.
+
+Hook interface is implemented in kernel/hook.c which can be compiled into the
+kernel or as a module based on the kernel compilation option specified in
+the "Kernel Hacking" section of the build configuration.
+
+Hooks are defined by coding a DECLARE_HOOK_HEAD macro to define a hook-head 
+structure and by calling hook_initialise() to inform Hook interface that the 
+hook exists and is usable. Modules defining hooks may load before or after 
+hook.o when it is compiled as a module, however they have to identify to the
+hook interface module the existence of a hook before an exit can be register 
+and arm itself.
+
+Hooks can be disabled from use by calling hook_terminate().
+
+Hooks are identified by name, which should avoid problems of uniqueness. The
+name specified is used to generate labels for the hook-head structure and the
+hook location.
+
+
+Installation:
+-------------
+
+Apply this patch to the kernel source and say 'Y' or 'M' to "Kernel Hooks 
+Interface" in the "Kernel Hacking" section of the build configuration. Build 
+the kernel and boot with it. If you build the hook interface as a module,
+build and install the module.
+
+-------------------------------------------------------------------------------
+If you want to see a working example then compile khook.c and kexit.c using 
+the following command:
+   
+gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -O2 -fomit-frame-pointer -DMODULE -DEXPORT_SYMTAB -DHOOK_DEBUG -c khook.c
+gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -O2 -fomit-frame-pointer -DMODULE -DEXPORT_SYMTAB -DHOOK_DEBUG -c kexit.c
+
+insmod khook.o
+insmod kexit.o
+
+khook.c shows how hooks are coded.
+kexit.c shows how hook exits register and arm themselves.
+
+There is a debug switch for  (-DHOOK_DEBUG) that can be specified at compile
+time. This will build in debugging printk calls.
+
+The procedure for defining and using hooks involves the following steps:
+	- add hooks to the kernel/kernel module source
+	- initialise hooks
+	- register hook exits
+	- arm hook exits
+and when we are done using the hooks, undo the above:
+	- disarm hook exits
+	- deregister hook exits
+	- terminate hooks
+
+-------------------------------------------------------------------------------
+
+Adding Hooks to the Kernel
+--------------------------
+
+Let's say we want to place a hook named hook_trap1_entry in the beginning of the
+trap1 handler then edit arch/i386/traps.c, locate routine do_debug. This is the
+trap1 exception handler. The code begins as follows:
+
+asmlinkage void do_debug(struct pt_regs * regs, long error_code)
+{
+	unsigned int condition;
+	struct task_struct *tsk = current;
+
+	if (regs->eflags & VM_MASK)
+		goto debug_vm86;
+
+	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
+
+Suppose we want a hook before the if statement. We add to traps.c:
+
+#include <linux/hook.h>
+#define HOOK_TRAP1_ENTRY hook_trap1_entry /* just a convenient define */
+DECLARE_HOOK_HEAD(HOOK_TRAP1_ENTRY);
+
+then in do_debug we insert the hook definition:
+asmlinkage void do_debug(struct pt_regs * regs, long error_code)
+{
+	unsigned int condition;
+	struct task_struct *tsk = current;
+
+	HOOK(HOOK_TRAP1_ENTRY);
+
+	if (regs->eflags & VM_MASK)
+		goto debug_vm86;
+
+	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
+
+Now recompile the kernel.
+
+For example to pass "condition" from do_debug to a hook exit:
+
+    HOOK(HOOK_TRAP1_ENTRY, condition);
+
+If you want to code a conditional-return hook the use for exmaple:
+
+    HOOK_RET(HOOK_TRAP1_ENTRY, condition);
+
+The kernel now has a dormant hook at the beginning of the trap1 exception
+handler.
+
+Adding Hooks to a Kernel Module
+-------------------------------
+Adding hooks to a kernel module is very similar to adding hooks to kernel.
+In the module that is to have a hook defined code the DECLARE_HOOK_HEAD macro 
+before the first routine is defined - in other words where external static 
+variables would be defined. For example suppose we wish to define my_hook,
+then code:
+
+#include <linux/hook.h>
+DECLARE_HOOK_HEAD(my_hook);
+
+Next you'll need to define the hook by coding a HOOK macro in the code path 
+where the hook is to be placed. In this example:
+
+	HOOK(my_hook);
+
+would be coded. This defines a public symbol for the hook location using the
+name my_hook.
+
+Initializing a Hook:
+-------------------
+Before any exit can register an exit for this hook you must identify it to
+the hook interface by calling hook_initialise. In this example you would code:
+	rc = hook_initialise(my_hook);
+0 will be return if successful.
+
+After this point exits may register and arm themselves for this hook.
+
+Before the module containing the hook terminates, it must be disabled 
+to stop any further registrations and optionally to force the hook to become
+inactive - that is to immediately stop any exits armed for this hook to become
+disarmed. To disale my_hook call hook_terminate as follows:
+
+	rc = hook_terminate(my_hook);
+
+The hook id you chose my be define by a symbol, for example:
+
+#define HOOK1 my_hook
+
+
+Using Hooks - registering and arming hook exits:
+------------------------------------------------
+
+To use this hook from your kernel module you need to perform 3 actions:
+
+1) If hook interface hook.o is built as a module, insert it using:
+	insmod hook.o
+you might need the -f switch if you've changed kernel  versions after
+compiling hook.o
+
+2) You need to register the entry point (the hook exit) in your kernel module
+that will receive control from hook.
+
+You do this by calling hook_exit_register passing a hook name (in this example
+HOOK_TRAP1_ENTRY) and a pointer to a hook record structure (defined in
+hook.h as hook_rec_t). You will need to include linux/hook.h into your module's 
+source. Refer to this file for the definition of hook_rec_t and the relavent
+flags.
+
+Allocate an instance of this structure for each hook exit you wish to
+register. The hook.o interface will use these structures for as long as your
+exits remain registered so allocate them from persistent memory e.g. the
+kernel heap or global memory in you module. Don't allocate them as local
+variables!
+
+You set up your hook record as follows:
+
+1) initialise the entire structure to NULLs.
+
+2) set hook_exit to the address of you hook routine.
+
+3) optionally set hook_flags to one of the following:
+
+#define HOOK_PRIORITY_FIRST	0x00000004
+#define HOOK_PRIORITY_LAST	0x00000008
+#define HOOK_QUEUE_LIFO		0x00000010
+
+HOOK_PRIORITY_FIRST inserts your exit at the head of the queue of exits to be 
+dispatched for the particular hook. If another exit has already registered with
+HOOK_PRIORITY_FIRST, then your registration fails.
+
+HOOK_PRIORITY_LAST inserts your exit at the tail of the dispatching
+queue. If another exit has already registered with this priority, then your 
+registration fails.
+
+Set HOOK_QUEUE_LIFO if you want to be inserted at the head of those exits that
+can happily co-exist, but after a HOOK_PRIORITY_FIRST exit if one exists. 
+
+If you leave hook_flag to NULL you'll be inserted at the tail, but above a 
+HOOK_PRIORITY_LAST exit if it exists.
+
+You now call hook_exit_register. If you get a NO_ERROR result then your exit has
+been successfully registered. Note: registration does not cause your exit to be
+called - that only happens after arming you exit. The reason for making this
+distinction is to allow a group of exits to be simultaneously armed, once
+successfully registered.
+
+On successful registration you hook record will have hook_index indicating the
+current position of this exit in the list of all exits registered for this 
+hook, i.e., its dispatching priority (1 being first). Note that it will be 
+updated as more exits register or deregister.
+
+To get a group of exits callable from the hook you need to arm them. They
+can be armed simultaneously, but note that arming is not necessarily atomic 
+under multiple processors. Arming is done by calling hook_exit_arm and 
+passing a pointer to the first of a group of hook records linked by hook_link. 
+The last in the list must have hook_link set to NULL, so if only one exit is 
+armed at a time then hook_link will be NULL.
+
+Once this is done your exits will be called whenever the kernel executes a
+HOOK statement - unless a higher priority exit set a non-zero return value.
+
+Hook Exit Parameters and Return Values.
+--------------------------------------
+A hook exit receives a variable length parameter list defined as follows:
+
+For normal (unconditional return) hooks:
+
+parm 0: pointer to the hook record structure. This is useful if you have the
+	same exit routine registered for multiple hooks, in which case this
+	can be used to determine which hook has caused the exit routine to be
+	called. 
+parm 1 to (n+1): parameters coded on the HOOK macros.
+
+For conditional-return hooks:
+
+parm 0: pointer to the hook record structure. This is useful if you have the
+	same exit routine registered for multiple hooks, in which case this
+	can be used to determine which hook has caused the exit routine to be
+	called. 
+parm 1: pointer to the return code (int *) to be set if a forced return of the
+	hooked routine is requested by the exit routine. 
+parm 2 to (n+2): parameters coded on the HOOK macros.
+
+If the exit function's prototype does not match the expected prototype, then
+the kernel could oops.
+
+A hook exit may itself return with the following return values:
+
+HOOK_CONTINUE - allows dispatching of other exits.
+HOOK_TERMINATE - stops further exit dispatching and returns to the hooked code.
+HOOK_RETURN - stops further exit dispatching and for conditional return hooks
+forces the hooked routine to return using parm2 as a return value.
+
+It is possible to write a hook exit function that takes variable number of
+arguments, see kexit.c for an example.
+
+Deregistering and disarming exits
+---------------------------------
+
+Exits may be disarmed and re-armed as often as like. Disarming may be done two
+ways:
+
+1) by calling hook_exit_disarm and passing a pointer to a hook record, which 
+may be linked optionally to a list of hook records, via hook_link, to be 
+disarmed simultaneously.
+
+2) by turning off HOOK_ARMED in hook_flags (&=~HOOK_ARMED) from the hook exit.
+
+Exits may be de-registered by calling hook_exit_deregister and passing a 
+pointer to a hook record, which may be linked optionally to a list of hook
+records, via hook_link, to be de-registered. De-registration will force 
+disarming.
+
+WARNING!!! A kernel module must deregister its exits from its module_cleanup
+routine if that have not already been deregistered. 
+
+/proc interface
+---------------
+When Generalized Kernel Hooks is initialized, a /proc/hooks directory is 
+created. Whenever a new hook is initialized, a /proc/hooks/<hook_id> 
+subdirectory is created. Whenever a new hook exit is registered, a 
+/proc/hooks/<hook_id>/<hook_exit_name> file is created. This file is writable 
+if hook_exit_register is called with the proc_writable set to 1, otherwise, 
+it is read-only. The file name is taken from hook_exit_name if set in the 
+hook_rec_t structure. If not set, the file name is the exit's memory location. 
+This file contains a boolean value of '1' or '0' to indicate whether the exit 
+is armed or not. It may be written to independently of GKHI to arm or disarm 
+a hook exit, provided that proc_writable flag is set on registration.
+
+Reporting Problems and Discussing GKHI
+--------------------------------------
+email: dprobes@oss.software.ibm.com
+vist: http://oss.software.ibm.com/developerworks/linux
+
+For further information read the USENIX 2000 Anual Linux Showcase paper, and
+the UKUUG Linux2001 Generalised Kernel Hooks paper which may be found at
+http://oss.software.ibm.com/developerworks/linux
+
+License
+-------
+Copyright (C) 2001 IBM Corporation
+
+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.
+
+Change History
+--------------
+0.6	8th November 2000	First public drop
+1.0	14th February 2001	SMP Enablement. Slim-line hooks implemented
+				Thanks to Andrea Arcangeli for suggestions for
+				improvement.
+1.1	12th April 2001		Hooks initialised dynamically.
+				Named hooks supported.
+				Conditonal return hooks supported.
+				Support for hooks in kernel modules added.
+1.2 	3rd July 2001		Bug fixes.
+				Rewrite to confirm to kernel coding style.
+				Make it part of the kernel build process.
+				Seperate out arch-dependent and indepedent
+				parts. Arch-independent hooks and convenient
+				provision to allow arch-specific optimized
+				implementation of hooks. Updated documentation
+				and simplify the sample modules.
+1.3	20th Sept. 2001		/proc interface
+				exclusive hooks
+1.4	4th Oct. 2001		HOOK macros now take variable number of args
+				Bug fix in is_asm_hook()
diff -Naur kernel.orig/linux24/Documentation/hook/kexit.c kernel/linux24/Documentation/hook/kexit.c
--- kernel.orig/linux24/Documentation/hook/kexit.c	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/Documentation/hook/kexit.c	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,265 @@
+/*****************************************************************************/
+/* Kernel Hooks Interface.                                    		     */
+/* Version 1.4                                                               */
+/* Author: Richard J Moore richardj_moore@uk.ibm.com                         */
+/* 	   Vamsi Krishna S. r1vamsi@in.ibm.com 				     */
+/*                                                                           */
+/* A sample kernel module registering exits for hooks defined in khook.o.    */
+/*                                                                           */
+/* Refer to Documentation/hook/HOWTO for details.                            */
+/*****************************************************************************/
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/hook.h>
+
+#define TEST_HOOK1 test_hook1
+#define TEST_HOOK2 test_hook2
+#define TEST_HOOK3 test_hook3
+#define TEST_HOOK4 test_hook4
+#define TEST_HOOK5 test_hook5
+int exit1(hook_rec_t *, int *);	/* first exit for test_hook1 */
+int exit2(hook_rec_t *);		/* first exit for test_hook2 */
+int exit3(hook_rec_t *, int *);	/* second exit for test_hook1 */
+int exit4(hook_rec_t *);		/* second exit for test_hook2 */
+int exit_var0(hook_rec_t *);
+int exit_var1(hook_rec_t *, int);
+int exit_var2(hook_rec_t *, int, int);
+int exit_var2_mismatch(hook_rec_t *, int);
+
+int ex_exit_var0(hook_rec_t *);
+int ex_exit_var1(hook_rec_t *, int);
+int ex_exit_var2(hook_rec_t *, int, int);
+int exit_var_args(hook_rec_t * hookrec, ...);
+extern int testhook(void);
+
+hook_rec_t hook1;
+hook_rec_t hook2;
+hook_rec_t hook3;
+hook_rec_t hook4;
+hook_rec_t var0;
+hook_rec_t var1;
+hook_rec_t var2;
+hook_rec_t ex_var0;
+hook_rec_t ex_var1;
+hook_rec_t ex_var2;
+
+int init_module(void)
+{
+	int rc;
+
+	hook1.hook_exit = &exit1;
+	hook1.hook_exit_name = "exit1";
+	rc = hook_exit_register(TEST_HOOK1, &hook1, 1);
+	DPRINTK("hook_exit_register exit1 for hook1 returned %u\n", rc);
+	if(rc) goto err;
+
+	hook2.hook_exit = &exit2;
+	hook2.hook_exit_name = "exit2";
+	rc = hook_exit_register(TEST_HOOK2, &hook2, 1);
+	DPRINTK("hook_exit_register exit2 for hook2 returned %u\n", rc);
+	if(rc) goto err1;
+
+	hook3.hook_exit = &exit3;
+	hook3.hook_exit_name = "exit3";
+	rc = hook_exit_register(TEST_HOOK1, &hook3, 1);
+	DPRINTK("hook_exit_register exit3 for hook1 returned %u\n", rc);
+	if(rc) goto err2;
+
+	hook4.hook_exit = &exit4;
+	hook4.hook_exit_name = "exit4";
+	rc = hook_exit_register(TEST_HOOK2, &hook4, 0);
+	DPRINTK("hook_exit_register exit4 for hook2 returned %u\n", rc);
+	if(rc) goto err3;
+
+
+	var0.hook_exit = &exit_var0;
+	rc = hook_exit_register(TEST_HOOK3, &var0, 0);
+	if(rc) goto err4;
+
+	var1.hook_exit = &exit_var1;
+	rc = hook_exit_register(TEST_HOOK4, &var1, 0);
+	if(rc) goto err5;
+
+	var2.hook_exit = &exit_var2_mismatch;
+	rc = hook_exit_register(TEST_HOOK5, &var2, 0);
+	if(rc) goto err6;
+
+	ex_var0.hook_exit = &ex_exit_var0;
+	rc = hook_exit_register(EX_TEST_HOOK3, &ex_var0, 0);
+	if(rc) goto err7;
+
+	ex_var1.hook_exit = &ex_exit_var1;
+	rc = hook_exit_register(EX_TEST_HOOK4, &ex_var1, 0);
+	if(rc) goto err8;
+
+//	ex_var2.hook_exit = &ex_exit_var2;
+	ex_var2.hook_exit = exit_var_args;
+	rc = hook_exit_register(EX_TEST_HOOK5, &ex_var2, 0);
+	if(rc) goto err9;
+
+	/* now arm all exits in a single operation */
+	hook1.hook_link = &hook2;
+	hook2.hook_link = &hook3;
+	hook3.hook_link = &hook4;
+	hook4.hook_link = &var0;
+	var0.hook_link = &var1;
+	var1.hook_link = &var2;
+	var2.hook_link = &ex_var0;
+	ex_var0.hook_link = &ex_var1;
+	ex_var1.hook_link = &ex_var2;
+	ex_var2.hook_link = NULL;
+
+	printk("hook exits are registered, but not yet armed.\n");
+
+	testhook();
+
+	rc = hook_exit_arm(&hook1);
+	DPRINTK("hook_exit_arm returned %u\n", rc);
+	if(rc) goto err10;
+
+	printk("hook exit are now armed.\n");
+
+	testhook();
+
+	printk("disarming exit1 only\n");
+	hook1.hook_link = NULL;
+	rc = hook_exit_disarm(&hook1);
+	DPRINTK("hook_exit_disarm returned %u\n", rc);
+	if(rc) goto error;
+
+	testhook();
+
+	DPRINTK("disarming exit2 only\n");
+	hook2.hook_link = NULL;
+	rc = hook_exit_disarm(&hook2);
+	DPRINTK("hook_exit_disarm returned %u\n", rc);
+	if(rc) goto error;
+
+	testhook();
+	return 0;
+	
+error:
+err10:	hook_exit_deregister(&ex_var2);
+err9:	hook_exit_deregister(&ex_var1);
+err8:	hook_exit_deregister(&ex_var0);
+err7:	hook_exit_deregister(&var2);
+err6:	hook_exit_deregister(&var1);
+err5:	hook_exit_deregister(&var0);
+err4:	hook_exit_deregister(&hook4);
+err3:	hook_exit_deregister(&hook3);
+err2:	hook_exit_deregister(&hook2);
+err1:	hook_exit_deregister(&hook1);
+err: 	return rc;
+}
+
+void cleanup_module(void)
+{
+	/* link all hook_rec structs and deregister */
+	hook1.hook_link = &hook2;
+	hook2.hook_link = &hook3;
+
+	hook_exit_deregister(&hook1);
+
+	printk("deregistered all hook exits.\n");
+
+	testhook();
+
+	return;
+}
+
+/* exit1 exit to test_hook1 */
+int exit1(hook_rec_t * hookrec, int *rc)
+{
+	printk("exit1: hook exit1 entered, indicate for testhook to return immediately\n");
+	*rc = 0;
+	printk("exit1: hook exit1 exiting\n");
+	return HOOK_RETURN;
+}
+
+/* exit2 exit to test_hook2 */
+int exit2(hook_rec_t * hookrec)
+{
+	printk("exit2: hook exit2 entered\n");
+	printk("exit2: hook exit2 exiting\n");
+	return HOOK_CONTINUE;
+}
+
+/* exit3 exit to test_hook1 */
+int exit3(hook_rec_t * hookrec, int *rc)
+{
+	printk("exit3: hook exit3 entered, allow testhook to continue\n");
+	*rc = 0;
+	printk("exit3: hook exit3 exiting\n");
+	return HOOK_CONTINUE;
+}
+
+/* exit4 exit to test_hook2 */
+int exit4(hook_rec_t * hookrec)
+{
+	printk("exit4: hook exit4 entered\n");
+	printk("exit4: hook exit4 exiting\n");
+	return HOOK_CONTINUE;
+}
+
+int exit_var0(hook_rec_t *hr)
+{
+	printk("exit_var0: entered\n");
+	printk("exit_var0: exiting\n");
+	return HOOK_CONTINUE;
+}
+int exit_var1(hook_rec_t *hr, int i)
+{
+	printk("exit_var1: entered, %x\n", i);
+	printk("exit_var1: exiting\n");
+	return HOOK_CONTINUE;
+}
+int exit_var2(hook_rec_t *hr, int i, int j)
+{
+	printk("exit_var2: entered %x, %x\n", i, j);
+	printk("exit_var2: exiting\n");
+	return HOOK_CONTINUE;
+}
+
+int exit_var2_mismatch(hook_rec_t *hr, int i)
+{
+	printk("exit_var2: entered using only the first arg: %x\n", i);
+	printk("exit_var2: exiting\n");
+	return HOOK_CONTINUE;
+}
+
+int ex_exit_var0(hook_rec_t *hr)
+{
+	printk("ex_exit_var0: entered %s\n", hr->hook_head->hook_id);
+	printk("ex_exit_var0: exiting\n");
+	return HOOK_CONTINUE;
+}
+int ex_exit_var1(hook_rec_t *hr, int i)
+{
+	printk("ex_exit_var1: entered, %x\n", i);
+	printk("ex_exit_var1: exiting\n");
+	return HOOK_CONTINUE;
+}
+int ex_exit_var2(hook_rec_t *hr, int i, int j)
+{
+	printk("ex_exit_var2: entered %x, %x\n", i, j);
+	printk("ex_exit_var2: exiting\n");
+	return HOOK_CONTINUE;
+}
+
+int exit_var_args(hook_rec_t * hookrec, ...)
+{
+	va_list args;
+	char buf[80];
+	char *fmt;
+	printk("exit_var_args: entered\n");
+	va_start(args, hookrec);
+	fmt = va_arg(args, char *);
+	vsprintf(buf, fmt, args);
+	printk("vsprintf output=%s\n", buf);
+	va_end(args);
+	printk("exit_var_args: exiting\n");
+	return HOOK_CONTINUE;
+}
diff -Naur kernel.orig/linux24/Documentation/hook/khook.c kernel/linux24/Documentation/hook/khook.c
--- kernel.orig/linux24/Documentation/hook/khook.c	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/Documentation/hook/khook.c	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,101 @@
+/*****************************************************************************/
+/* Kernel Hooks Interface.                                    		     */
+/* Version 1.4                                                               */
+/* Author: Richard J Moore richardj_moore@uk.ibm.com                         */
+/* 	   Vamsi Krishna S. r1vamsi@in.ibm.com 				     */
+/*                                                                           */
+/* A sample kernel module with hooks in it (in the testhook function).   */
+/*                                                                           */
+/* Refer to Documentation/hook/HOWTO for details.                            */
+/*****************************************************************************/
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/hook.h>
+
+#define TEST_HOOK1 test_hook1
+#define TEST_HOOK2 test_hook2
+#define TEST_HOOK3 test_hook3
+#define TEST_HOOK4 test_hook4
+#define TEST_HOOK5 test_hook5
+DECLARE_HOOK_HEAD(TEST_HOOK1);
+DECLARE_HOOK_HEAD(TEST_HOOK2);
+DECLARE_HOOK_HEAD(TEST_HOOK3);
+DECLARE_HOOK_HEAD(TEST_HOOK4);
+DECLARE_HOOK_HEAD(TEST_HOOK5);
+DECLARE_EXCLUSIVE_HOOK_HEAD(EX_TEST_HOOK3);
+DECLARE_EXCLUSIVE_HOOK_HEAD(EX_TEST_HOOK4);
+DECLARE_EXCLUSIVE_HOOK_HEAD(EX_TEST_HOOK5);
+
+int init_module(void)
+{
+	int rc;
+
+	rc = hook_initialise(TEST_HOOK1);
+	DPRINTK("hook_initialise returned %u\n", rc);
+	if(rc) 
+		return 1;
+
+	rc = hook_initialise(TEST_HOOK2);
+	DPRINTK("hook_initialise returned %u\n", rc);
+	if(rc) {
+		hook_terminate(TEST_HOOK1, 0);
+		return 1;
+	}
+	hook_initialise(TEST_HOOK3);
+	hook_initialise(TEST_HOOK4);
+	hook_initialise(TEST_HOOK5);
+	hook_initialise(EX_TEST_HOOK3);
+	hook_initialise(EX_TEST_HOOK4);
+	hook_initialise(EX_TEST_HOOK5);
+
+	DPRINTK("now load kexit.o to test the hook(s)\n");
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	int rc;
+
+	rc = hook_terminate(TEST_HOOK1, 0);
+	DPRINTK("hook_terminate returned %u\n", rc);
+
+	rc = hook_terminate(TEST_HOOK2, 0);
+	DPRINTK("hook_terminate returned %u\n", rc);
+
+	hook_terminate(TEST_HOOK3, 0);
+	hook_terminate(TEST_HOOK4, 0);
+	hook_terminate(TEST_HOOK5, 0);
+	hook_terminate(EX_TEST_HOOK3, 0);
+	hook_terminate(EX_TEST_HOOK4, 0);
+	hook_terminate(EX_TEST_HOOK5, 0);
+
+	return;
+}
+
+/*
+ * this is an example of how the hooks would be coded in the kernel or a
+ * kernel module.
+ */
+int testhook(void)
+{
+	printk("testhook entered\n");
+	
+	HOOK_RET(TEST_HOOK1);
+	HOOK(TEST_HOOK2);
+
+	HOOK(TEST_HOOK3);
+	HOOK(TEST_HOOK4, 4);
+	HOOK(TEST_HOOK5, 5, 0);
+
+	EXCLUSIVE_HOOK(EX_TEST_HOOK3);
+	EXCLUSIVE_HOOK(EX_TEST_HOOK4, 4);
+	EXCLUSIVE_HOOK(EX_TEST_HOOK5, "%s, %d", "test_hook3", 1);
+
+	printk("testhook exited\n");
+	return 0;
+}
+
+EXPORT_SYMBOL_NOVERS(testhook);
diff -Naur kernel.orig/linux24/Makefile kernel/linux24/Makefile
--- kernel.orig/linux24/Makefile	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/Makefile	Fri Jun 28 20:57:45 2002
@@ -185,6 +185,7 @@
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
+DRIVERS-$(CONFIG_DEBUG_KERNEL_STATE_TRACE) += drivers/lkst/lkstdrv.o
 
 DRIVERS := $(DRIVERS-y)
 
diff -Naur kernel.orig/linux24/arch/i386/boot/compressed/misc.c kernel/linux24/arch/i386/boot/compressed/misc.c
--- kernel.orig/linux24/arch/i386/boot/compressed/misc.c	Tue Nov 13 02:59:43 2001
+++ kernel/linux24/arch/i386/boot/compressed/misc.c	Fri Jun 28 20:57:45 2002
@@ -9,6 +9,7 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 
+#define LKST_SUPPRESS_PIO_TRACE
 #include <linux/linkage.h>
 #include <linux/vmalloc.h>
 #include <linux/tty.h>
diff -Naur kernel.orig/linux24/arch/i386/config.in kernel/linux24/arch/i386/config.in
--- kernel.orig/linux24/arch/i386/config.in	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/arch/i386/config.in	Fri Jun 28 20:57:45 2002
@@ -417,6 +417,13 @@
    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
+   tristate '  Kernel State Tracing (LKST)' CONFIG_DEBUG_KERNEL_STATE_TRACE
+if [ "$CONFIG_DEBUG_KERNEL_STATE_TRACE" = "y" ]; then
+   bool '    Enable in starting kernel' CONFIG_DEBUG_KERNEL_STATE_TRACE_IN_START
+fi
+if [ "$CONFIG_DEBUG_KERNEL_STATE_TRACE" != "n" ]; then
+   define_bool CONFIG_HOOK y
+fi
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
    bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
 fi
diff -Naur kernel.orig/linux24/arch/i386/kernel/entry.S kernel/linux24/arch/i386/kernel/entry.S
--- kernel.orig/linux24/arch/i386/kernel/entry.S	Sat Nov  3 10:18:49 2001
+++ kernel/linux24/arch/i386/kernel/entry.S	Fri Jun 28 20:57:45 2002
@@ -197,10 +197,74 @@
 	GET_CURRENT(%ebx)
 	testb $0x02,tsk_ptrace(%ebx)	# PT_TRACESYS
 	jne tracesys
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	.global LKST_ETYPE_SYSCALL_ENTRY_HEADER
+LKST_ETYPE_SYSCALL_ENTRY_HEADER:
+	movl $0, %eax
+	testl %eax, %eax
+	je .L_LKST11
+	movl LKST_ETYPE_SYSCALL_ENTRY_HEADER_head+8, %ebx
+	jmp .L_LKST12
+.L_LKST13:
+	movl 8(%ebx), %ebx
+.L_LKST12:
+	testb $1, 16(%ebx)
+	je .L_LKST13
+	movl ORIG_EAX(%esp), %eax	# get syscall number
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl %eax	# push syscall number
+	pushl $0
+	pushl $48	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST13
+.L_LKST11:
+        movl ORIG_EAX(%esp),%eax
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 	cmpl $(NR_syscalls),%eax
 	jae badsys
 	call *SYMBOL_NAME(sys_call_table)(,%eax,4)
 	movl %eax,EAX(%esp)		# save the return value
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	.global LKST_ETYPE_SYSCALL_EXIT_HEADER
+LKST_ETYPE_SYSCALL_EXIT_HEADER:
+	movl $0, %eax
+	testl %eax, %eax
+	je .L_LKST21
+	movl LKST_ETYPE_SYSCALL_EXIT_HEADER_head+8, %ebx
+	jmp .L_LKST22
+.L_LKST23:
+	movl 8(%ebx), %ebx
+.L_LKST22:
+	testb $1, 16(%ebx)
+	je .L_LKST23
+        movl ORIG_EAX(%esp),%eax	# get syscall number
+        movl EAX(%esp),%ecx		# get return value
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl %ecx	# push return value
+	pushl $0
+        pushl %eax  	# push syscall number
+	pushl $0
+	pushl $49	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST23
+.L_LKST21:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 ENTRY(ret_from_sys_call)
 	cli				# need_resched and signals atomic test
 	cmpl $0,need_resched(%ebx)
@@ -287,8 +351,66 @@
 	movl %edx,%ds
 	movl %edx,%es
 	GET_CURRENT(%ebx)
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	movl LKST_ETYPE_EXCEPTION_ENTRY_HEADER_head+16, %eax
+	testl %eax, %eax
+	jns .L_LKST31
+	movl LKST_ETYPE_EXCEPTION_ENTRY_HEADER_head+8, %ebx
+	jmp .L_LKST32
+.L_LKST33:
+	movl 8(%ebx), %ebx
+.L_LKST32:
+	testb $1, 16(%ebx)
+	je .L_LKST33
+	pushl $0
+	pushl $0
+	pushl 56(%esp)	# exception address
+	pushl $0
+        pushl %esi	# push the error code 
+	pushl $0
+        pushl %edi	# push the function address
+	pushl $0
+	pushl $32	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $8, %esp	# modify stack pointer
+        popl %edi	# pop the function address into edi
+	addl $24, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST33
+.L_LKST31:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */	
 	call *%edi
 	addl $8,%esp
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+16, %eax
+	testl %eax, %eax
+	jns .L_LKST41
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+8, %ebx
+	jmp .L_LKST42
+.L_LKST43:
+	movl 8(%ebx), %ebx
+.L_LKST42:
+	testb $1, 16(%ebx)
+	je .L_LKST43
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+        pushl %edi	# push the exception handler address
+	pushl $0
+	pushl $33	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST43
+.L_LKST41:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 	jmp ret_from_exception
 
 ENTRY(coprocessor_error)
@@ -305,15 +427,99 @@
 	pushl $-1		# mark this as an int
 	SAVE_ALL
 	GET_CURRENT(%ebx)
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	movl LKST_ETYPE_EXCEPTION_ENTRY_HEADER_head+16, %eax
+	testl %eax, %eax
+	jns .L_LKST51
+	movl LKST_ETYPE_EXCEPTION_ENTRY_HEADER_head+8, %ecx
+	jmp .L_LKST52
+.L_LKST53:
+	movl 8(%ecx), %ecx
+.L_LKST52:
+	testb $1, 16(%ecx)
+	je .L_LKST53
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+        pushl $0	# push a dummy value
+	pushl $0
+        pushl $7	# push the exception No.7
+	pushl $0
+	pushl $32	# push event type
+	pushl %ecx
+	call *(%ecx)	# call handler
+        popl %ecx	# pop ecx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST53
+.L_LKST51:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 	movl %cr0,%eax
 	testl $0x4,%eax			# EM (math emulation bit)
 	jne device_not_available_emulate
 	call SYMBOL_NAME(math_state_restore)
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+16, %eax
+	testl %eax, %eax
+	jns .L_LKST81
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+8, %ebx
+	jmp .L_LKST82
+.L_LKST83:
+	movl 8(%ebx), %ebx
+.L_LKST82:
+	testb $1, 16(%ebx)
+	je .L_LKST83
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+        pushl $math_state_restore	# push handler address
+	pushl $0
+	pushl $33	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST83
+.L_LKST81:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 	jmp ret_from_exception
 device_not_available_emulate:
 	pushl $0		# temporary storage for ORIG_EIP
 	call  SYMBOL_NAME(math_emulate)
 	addl $4,%esp
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+16, %eax
+	testl %eax, %eax
+	jns .L_LKST91
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+8, %ebx
+	jmp .L_LKST92
+.L_LKST93:
+	movl 8(%ebx), %ebx
+.L_LKST92:
+	testb $1, 16(%ebx)
+	je .L_LKST93
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+        pushl $math_emulate	# push handler address
+	pushl $0
+	pushl $33	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST93
+.L_LKST91:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 	jmp ret_from_exception
 
 ENTRY(debug)
@@ -324,11 +530,67 @@
 ENTRY(nmi)
 	pushl %eax
 	SAVE_ALL
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	movl LKST_ETYPE_EXCEPTION_ENTRY_HEADER_head+16, %eax
+	testl %eax, %eax
+	jns .L_LKST61
+	movl LKST_ETYPE_EXCEPTION_ENTRY_HEADER_head+8, %ebx
+	jmp .L_LKST62
+.L_LKST63:
+	movl 8(%ebx), %ebx
+.L_LKST62:
+	testb $1, 16(%ebx)
+	je .L_LKST63
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+        pushl $0	# push a dummy value
+	pushl $0
+        pushl $2	# push the exception No.2
+	pushl $0
+	pushl $32	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST63
+.L_LKST61:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 	movl %esp,%edx
 	pushl $0
 	pushl %edx
 	call SYMBOL_NAME(do_nmi)
 	addl $8,%esp
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+16, %eax
+	testl %eax, %eax
+	jns .L_LKST71
+	movl LKST_ETYPE_EXCEPTION_EXIT_HEADER_head+8, %ebx
+	jmp .L_LKST72
+.L_LKST73:
+	movl 8(%ebx), %ebx
+.L_LKST72:
+	testb $1, 16(%ebx)
+	je .L_LKST73
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+	pushl $0
+        pushl $2	# push the exception No.2
+	pushl $0
+	pushl $33	# push event type
+	pushl %ebx
+	call *(%ebx)	# call handler
+        popl %ebx	# pop ebx
+	addl $36, %esp	# modify stack pointer
+	testl %eax, %eax
+	je .L_LKST73
+.L_LKST71:
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
 	RESTORE_ALL
 
 ENTRY(int3)
diff -Naur kernel.orig/linux24/arch/i386/kernel/irq.c kernel/linux24/arch/i386/kernel/irq.c
--- kernel.orig/linux24/arch/i386/kernel/irq.c	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/arch/i386/kernel/irq.c	Fri Jun 28 20:57:45 2002
@@ -44,7 +44,7 @@
 #include <asm/desc.h>
 #include <asm/irq.h>
 
-
+#include <linux/lkst.h>
 
 /*
  * Linux has a controller-independent x86 interrupt architecture.
@@ -620,7 +620,11 @@
 	 * SMP environment.
 	 */
 	for (;;) {
-		spin_unlock(&desc->lock);
+        LKST_HOOK(LKST_ETYPE_INT_HARDWARE_ENTRY,
+			LKST_ARG32(irq,0), LKST_ARG32(status,0),
+			LKST_ARG32(0,0),
+			LKST_ARG32(0,0) );
+	        spin_unlock(&desc->lock);
 		handle_IRQ_event(irq, &regs, action);
 		spin_lock(&desc->lock);
 		
diff -Naur kernel.orig/linux24/arch/i386/kernel/process.c kernel/linux24/arch/i386/kernel/process.c
--- kernel.orig/linux24/arch/i386/kernel/process.c	Fri Oct  5 10:42:54 2001
+++ kernel/linux24/arch/i386/kernel/process.c	Fri Jun 28 20:57:45 2002
@@ -49,6 +49,8 @@
 
 #include <linux/irq.h>
 
+#include <linux/lkst.h>
+
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 int hlt_counter;
@@ -488,6 +490,10 @@
 {
 	long retval, d0;
 
+	LKST_HOOK(LKST_ETYPE_PROCESS_LTHREADGEN,
+		LKST_ARG32(fn,0), LKST_ARG32(arg,0),
+		LKST_ARG32(flags,0), LKST_ARG32(0,0));
+
 	__asm__ __volatile__(
 		"movl %%esp,%%esi\n\t"
 		"int $0x80\n\t"		/* Linux/i386 system call */
diff -Naur kernel.orig/linux24/arch/i386/kernel/sys_i386.c kernel/linux24/arch/i386/kernel/sys_i386.c
--- kernel.orig/linux24/arch/i386/kernel/sys_i386.c	Tue Mar 20 05:35:09 2001
+++ kernel/linux24/arch/i386/kernel/sys_i386.c	Fri Jun 28 20:57:45 2002
@@ -22,6 +22,8 @@
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 
+#include <linux/lkst.h>
+
 /*
  * sys_pipe() is the normal C calling standard for creating
  * a pipe. It's not the way Unix traditionally does this, though.
@@ -134,6 +136,12 @@
 {
 	int version, ret;
 
+	LKST_HOOK(LKST_ETYPE_SYSV_IPC,
+		       LKST_ARG32(call, first),
+		       LKST_ARG32(second, third),
+		       LKST_ARG32(ptr, 0),
+		       LKST_ARG32(0, 0));
+
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
diff -Naur kernel.orig/linux24/drivers/Makefile kernel/linux24/drivers/Makefile
--- kernel.orig/linux24/drivers/Makefile	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/drivers/Makefile	Fri Jun 28 20:57:45 2002
@@ -8,7 +8,7 @@
 
 mod-subdirs :=	dio mtd sbus video macintosh usb input telephony sgi ide \
 		message/i2o message/fusion scsi md ieee1394 pnp isdn dump atm \
-		fc4 net/hamradio i2c acpi bluetooth
+		fc4 net/hamradio i2c acpi bluetooth lkst
 
 subdir-y :=	parport char block net sound misc media cdrom hotplug
 subdir-m :=	$(subdir-y)
@@ -48,4 +48,6 @@
 
 subdir-$(CONFIG_BLUEZ)		+= bluetooth
 
+subdir-$(CONFIG_DEBUG_KERNEL_STATE_TRACE) += lkst
+
 include $(TOPDIR)/Rules.make
diff -Naur kernel.orig/linux24/drivers/block/ll_rw_blk.c kernel/linux24/drivers/block/ll_rw_blk.c
--- kernel.orig/linux24/drivers/block/ll_rw_blk.c	Tue Oct 30 05:11:17 2001
+++ kernel/linux24/drivers/block/ll_rw_blk.c	Fri Jun 28 20:57:45 2002
@@ -31,6 +31,8 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 
+#include <linux/lkst.h>
+
 /*
  * MAC Floppy IWM hooks
  */
@@ -1011,6 +1013,12 @@
 		}
 
 		submit_bh(rw, bh);
+
+		LKST_HOOK(LKST_ETYPE_FS_DEVRW,
+			       LKST_ARG32(bh, 0),
+			       LKST_ARG32(rw, 0),
+			       LKST_ARG32(nr, 0),
+			       LKST_ARG32(0, 0));
 	}
 	return;
 
diff -Naur kernel.orig/linux24/drivers/char/sysrq.c kernel/linux24/drivers/char/sysrq.c
--- kernel.orig/linux24/drivers/char/sysrq.c	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/drivers/char/sysrq.c	Fri Jun 28 20:57:45 2002
@@ -412,7 +412,7 @@
 /* s */	&sysrq_sync_op,
 /* t */	&sysrq_showstate_op,
 /* u */	&sysrq_mountro_op,
-/* v */	NULL,
+/* v */	NULL, /* This will often be registered as 'lkstView' at init time */
 /* w */	NULL,
 /* x */	NULL,
 /* w */	NULL,
diff -Naur kernel.orig/linux24/drivers/lkst/Makefile kernel/linux24/drivers/lkst/Makefile
--- kernel.orig/linux24/drivers/lkst/Makefile	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/drivers/lkst/Makefile	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,16 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := lkstdrv.o
+
+export-objs = lkst.o
+
+obj-$(CONFIG_DEBUG_KERNEL_STATE_TRACE) = lkst.o
+
+include $(TOPDIR)/Rules.make
diff -Naur kernel.orig/linux24/drivers/lkst/lkst.c kernel/linux24/drivers/lkst/lkst.c
--- kernel.orig/linux24/drivers/lkst/lkst.c	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/drivers/lkst/lkst.c	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,3753 @@
+/* $Id: lkst.c,v 1.10 2002/06/28 11:27:55 indoh Exp $ */ 
+/* linux/drivers/lkst/lkst.c */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by K.Serizawa <serizawa@sdl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/sysrq.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/lkst_private.h>
+#include <linux/stat.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/spinlock.h>
+#include <linux/utsname.h>
+
+// TODO: check architecture independency
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+
+				/* Array of mnemonics of event types */
+#define LKST_ETYPE_DEF_MNEMONICS
+
+#include <linux/lkst_events.h>
+
+				/* Array of descriptions of event types */
+#define LKST_ETYPE_DEF_DESCRIPTIONS
+
+#include <linux/lkst_events.h>
+
+		/* Error code for lkst_evhandlerprim_buffer_shift_inline() */
+#define LKST_BUFFER_SHIFT_ERRNO_SUCCESS	0
+#define LKST_BUFFER_SHIFT_ERRNO_ECPU	(-1)
+#define LKST_BUFFER_SHIFT_ERRNO_ECBUF	(-2)
+#define LKST_BUFFER_SHIFT_ERRNO_ENBUF	(-3)
+#define LKST_BUFFER_SHIFT_ERRNO_EBUFC	(-4)
+
+		/* Error code for lkst_evhandlerprim_maskset_xchg_inline() */
+#define LKST_MASKSET_XCHG_ERRNO_SUCCESS	0
+#define LKST_MASKSET_XCHG_ERRNO_WCID	(-1)
+#define LKST_MASKSET_XCHG_ERRNO_WCPT	(-2)
+#define LKST_MASKSET_XCHG_ERRNO_ECPT	(-3)
+#define LKST_MASKSET_XCHG_ERRNO_ENID	(-4)
+#define LKST_MASKSET_XCHG_ERRNO_ENPT	(-5)
+#define LKST_MASKSET_XCHG_ERRNO_ESTAT	(-6)
+
+
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE
+extern struct lkst_header lkst;
+#else /* !CONFIG_DEBUG_KERNEL_STATE_TRACE */
+#define lkst (*((struct lkst_header *)get_lkst()))
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE */
+
+#define cpu_khz (lkst_get_cpu_khz())
+
+EXPORT_SYMBOL(lkst_trc_status);
+EXPORT_SYMBOL(lkst_trc_start);
+EXPORT_SYMBOL(lkst_trc_stop);
+EXPORT_SYMBOL(lkst_maskset_xchg);
+EXPORT_SYMBOL(lkst_maskset_set);
+EXPORT_SYMBOL(lkst_maskset_read);
+EXPORT_SYMBOL(lkst_maskset_write);
+EXPORT_SYMBOL(lkst_maskset_delete);
+EXPORT_SYMBOL(lkst_maskset_list);
+EXPORT_SYMBOL(lkst_evhandler_ctrl);
+EXPORT_SYMBOL(lkst_evhandler_list);
+EXPORT_SYMBOL(lkst_evhandler_register);
+EXPORT_SYMBOL(lkst_buffer_read);
+EXPORT_SYMBOL(lkst_buffer_create);
+EXPORT_SYMBOL(lkst_buffer_shift);
+EXPORT_SYMBOL(lkst_buffer_delete);
+#if DEBUG
+EXPORT_SYMBOL(lkst_buffer_seek);
+#endif /* DEBUG */
+EXPORT_SYMBOL(lkst_buffer_list);
+EXPORT_SYMBOL(lkst_buffer_dump_current_txt);
+EXPORT_SYMBOL(lkst_evhandlerprim_select_buffer_cpu);
+EXPORT_SYMBOL(lkst_evhandlerprim_select_buffer_id);
+EXPORT_SYMBOL(lkst_evhandlerprim_select_buffer);
+EXPORT_SYMBOL(lkst_evhandlerprim_recid_inc);
+EXPORT_SYMBOL(lkst_evhandlerprim_get_write_entry);
+EXPORT_SYMBOL(lkst_evhandlerprim_getw_buffer);
+EXPORT_SYMBOL(lkst_evhandlerprim_getw_buffer_cpu);
+EXPORT_SYMBOL(lkst_evhandlerprim_putw_buffer);
+EXPORT_SYMBOL(lkst_evhandlerprim_daemon_wakeup);
+EXPORT_SYMBOL(lkst_evhandlerprim_entry_log_l2);
+EXPORT_SYMBOL(lkst_evhandler_default);
+EXPORT_SYMBOL(lkst_evhandler_default_ctrl);
+EXPORT_SYMBOL(lkst_evhandler_buffer_shift);
+EXPORT_SYMBOL(lkst_evhandler_maskset_xchg);
+EXPORT_SYMBOL(lkst_evhandler_buffer_shift_dw);
+EXPORT_SYMBOL(lkst_event_type_mnemonics);
+EXPORT_SYMBOL(lkst_event_type_descriptions);
+EXPORT_SYMBOL(lkst_hook_init_module);
+EXPORT_SYMBOL(lkst_hook_reset_all);
+#if DEBUG
+EXPORT_SYMBOL(lkst_evhandler_exception);
+#endif /* DEBUG */
+
+int lkst_init_flag = LKST_FLAG_NO; // TODO: not used
+static size_t lkst_init_buffer_size = LKST_BUFFER_SIZE_DEFAULT;
+static struct lkst_event_buffer lkst_stage0_event_buffer = {
+	writep:{LKST_BUFFER_HEADSPACE},
+	size:LKST_BUFFER_SIZE_DEFAULT,
+	readp:LKST_BUFFER_HEADSPACE,
+	id:0,next:LKST_BUFFER_ID_VOID,prev:LKST_BUFFER_ID_VOID,
+	eyecatcher:{'L','K','B','F'},
+	cpu:0,
+	last_recid:0,
+	last_readp:(LKST_BUFFER_HEADSPACE - sizeof (struct lkst_event_record)) & (LKST_BUFFER_SIZE_DEFAULT - 1),
+	xtime:{0, 0},
+	cmos_time_flag:1,
+	buf_ver:LKST_BUF_VER,
+	rcnt:{0},
+	wcnt:{0}
+};
+spinlock_t lkst_buffer_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t lkst_status_lock = SPIN_LOCK_UNLOCKED;
+
+/* definitions of special masksets. */
+/*
+ * maskset_rnothing (id: 0(LKST_MASKSET_ID_RNOTHING))
+ * a maskset to record no events.
+ */
+static const lkst_evhandler_id maskset_rnothing[] = {
+	[0 ... LKST_ETYPE_MAX] = LKST_EVHANDLER_ID_VOID
+	    /* caution: LKST_ETYPE_MAX is significant
+	     *   to decide the size of this maskset.
+	     */
+};
+
+/*
+ * maskset_rall (id: 1(LKST_MASKSET_ID_RALL))
+ * a maskset to record all events.
+ */
+static const lkst_evhandler_id maskset_rall[] = {
+	[0 ... LKST_ETYPE_LKST_BUFF_OVFLOW - 1] = LKST_EVHANDLER_ID_DEFAULT,
+	[LKST_ETYPE_LKST_BUFF_OVFLOW] = LKST_EVHANDLER_ID_BUFFER_SHIFT,
+	[LKST_ETYPE_LKST_BUFF_OVFLOW + 1 ... LKST_ETYPE_MAX] = LKST_EVHANDLER_ID_DEFAULT
+	    /* caution: LKST_ETYPE_MAX is significant, ditto. */
+};
+
+/*
+ * maskset_rdefault (id: 2(LKST_MASKSET_ID_RDEFAULT))
+ * a maskset selected initially.
+ */
+static const lkst_evhandler_id maskset_rdefault[] = {
+	/* Default Maskset omits lock operation events */
+
+	[0 ... LKST_ETYPE_LK_SPINLOCK - 1] = LKST_EVHANDLER_ID_DEFAULT,
+	[LKST_ETYPE_LK_SPINLOCK ... LKST_ETYPE_O_PORTOUT] = LKST_EVHANDLER_ID_VOID,
+	[LKST_ETYPE_O_PORTOUT + 1 ... LKST_ETYPE_LKST_BUFF_OVFLOW - 1] = LKST_EVHANDLER_ID_DEFAULT,
+	[LKST_ETYPE_LKST_BUFF_OVFLOW] = LKST_EVHANDLER_ID_BUFFER_SHIFT,
+	[LKST_ETYPE_LKST_BUFF_OVFLOW + 1 ... LKST_ETYPE_MAX] = LKST_EVHANDLER_ID_DEFAULT
+	    /* caution: LKST_ETYPE_MAX is significant, ditto. */
+};
+
+/* LKST device file_operations */
+static struct file_operations lkst_fops = {
+	ioctl:lkst_ioctl,
+	open:lkst_open,
+	read:lkst_read,
+	write:NULL,
+	poll:NULL,
+	release:lkst_close,
+	lock:NULL,
+};
+
+#if DEBUG
+/* for ioctl(LKST_IOC_DIAG) */
+#define LKST_IOC_DIAG		0xfe
+
+struct lkst_diag_arg {
+	int (*func) (char *arg);
+	char arg[128];
+} lkst_diag_argdata[LKST_CPU_MAX];
+
+static int lkst_ioc_diag(long arg);
+#endif /* DEBUG */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static void sysrq_handle_lkst_dump_buffer(int key, struct pt_regs *pt_regs,
+					  struct kbd_struct *kbd,
+					  struct tty_struct *tty)
+{
+	lkst_buffer_dump_current_txt();
+}
+
+static struct sysrq_key_op sysrq_lkst_dump_buffer_op = {
+	handler:sysrq_handle_lkst_dump_buffer,
+	help_msg:"lkstView",
+	action_msg:"Dump Buffer\n",
+};
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+/* for devfs support */
+#ifdef CONFIG_DEVFS_FS
+static devfs_handle_t lkst_devfs_handle = NULL;
+#endif	
+
+/*********************************************************************
+ *  Kernel hook functions
+ *********************************************************************/
+
+
+/* 
+ *
+ *  GKHI hook function
+ *
+ */
+
+extern void lkst_trc_hook_init(void);
+extern void lkst_trc_hook_cleanup(void);
+
+/* Exchange of hook exit */
+static __inline__ int lkst_hook_exit_xchg(lkst_event_type etype, 
+					  lkst_evhandler_id newid,
+					  lkst_evhandler_id oldid)
+{
+	int ret = 0;
+	hook_rec_t* phookrec = lkst_hook_info_table[etype].phookrec;
+	lkst_evhandler_func new_evhandler;
+
+	if(phookrec == NULL) return 0;
+
+	/* unregister old exit */
+	if(oldid <= LKST_EVHANDLER_ID_MAX){
+		hook_exit_deregister(phookrec);
+		memset(phookrec, 0, sizeof(hook_rec_t));
+	}
+
+	/* register new exit */
+	if(newid <= LKST_EVHANDLER_ID_MAX){
+		if (!LKST_POINTER_VERIFY
+		    (lkst.evhandler_table[newid].evhandler, new_evhandler)) {
+			/* Handler(ID=newid) does not exist. */
+			return 0;
+		}
+		phookrec->hook_exit = new_evhandler;
+		/* phookrec->hook_exit_name = lkst.evhandler_table[newid].name; */
+		phookrec->hook_link = NULL;
+		ret = _hook_exit_register(lkst_hook_info_table[etype].hook_id,
+					  phookrec, 0);
+		ret += hook_exit_arm(phookrec);
+	}
+	return ret;
+}
+
+
+/* 
+ * Exchange maskset
+ *  Called from lkst_trc_init_stage0, lkst_evhandlerprim_maskset_xchg_inline,
+ *  lkst_trc_start_core and lkst_trc_stop_core.
+ */
+int lkst_hook_maskset_xchg(lkst_maskset_id mask_id_new,
+			   lkst_maskset_id mask_id_old)
+{
+	int i, ret = 0;
+	lkst_maskset *maskset_old;
+	lkst_maskset *maskset_new;
+	lkst_evhandler_id evh_id_old;
+	lkst_evhandler_id evh_id_new;
+
+	if(mask_id_old == mask_id_new) return 0;
+
+	if (mask_id_old > LKST_MASKSET_ID_MAX) {
+		mask_id_old = LKST_MASKSET_ID_RNOTHING;
+	}
+	if (mask_id_new > LKST_MASKSET_ID_MAX) {
+		mask_id_new = LKST_MASKSET_ID_RDEFAULT;
+	}
+
+	maskset_old = lkst.maskset_table[mask_id_old].masksetp;
+	maskset_new = lkst.maskset_table[mask_id_new].masksetp;
+
+	for (i = 0; i < LKST_MASKSET_TABLE_LEN_MAX; i++) {
+		evh_id_old = LKST_MASKSET_QUERY_EVHANDLER_ID(maskset_old, i);
+		evh_id_new = LKST_MASKSET_QUERY_EVHANDLER_ID(maskset_new, i);
+
+		if(evh_id_old != evh_id_new) {
+			ret = lkst_hook_exit_xchg(i, evh_id_new, evh_id_old);
+		}
+	}
+
+	if (ret) {
+		printk(KERN_ERR "LKST error(hook_maskset_xchg): hook_maskset_xchg failed: %u\n", ret);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* 
+ * Update hook exit
+ *  Called from lkst_evhandler_register
+ */
+static __inline__ int lkst_hook_exit_update(lkst_evhandler_id evh_id)
+{
+	lkst_evhandler_id evhandler_id;
+	lkst_maskset *maskset = NULL;
+	int i, ret = 0;
+
+	if (!LKST_POINTER_VERIFY(lkst.current_masksetp, maskset)) {
+		/* lkst_evhandler_register is called from stage0 */
+		return 0;
+	}
+
+	for(i=0; i<LKST_MASKSET_TABLE_LEN_MAX; i++){
+		evhandler_id = LKST_MASKSET_QUERY_EVHANDLER_ID(maskset, i);
+		if(evhandler_id == evh_id){
+			ret += lkst_hook_exit_xchg(i, evh_id, 0);
+		}
+	}
+
+	if (ret) {
+		printk(KERN_ERR "LKST error(hook_exit_update): hook_exit_update failed: %u\n", ret);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* 
+ * Initialize hook in the modules
+ */
+void lkst_hook_init_module(lkst_event_type etype)
+{
+	lkst_evhandler_id evhandler_id;
+	lkst_maskset *maskset = NULL;
+
+	if ((etype > LKST_ETYPE_MAX) || (etype < 0)) {
+		printk(KERN_ERR "LKST error(lkst_hook_init_module): invalid event id %u\n", etype);
+		return;
+	}
+
+	if (!LKST_POINTER_VERIFY(lkst.current_masksetp, maskset)) {
+		return;
+	}
+
+	evhandler_id = LKST_MASKSET_QUERY_EVHANDLER_ID(maskset, etype);
+	lkst_hook_exit_xchg(etype, evhandler_id, LKST_EVHANDLER_ID_MAX + 1);
+}
+
+/* 
+ * Reset all hook
+ */
+void lkst_hook_reset_all(void)
+{
+	lkst_hook_maskset_xchg(LKST_MASKSET_ID_RNOTHING, LKST_MASKSET_ID_RALL);
+	lkst_hook_maskset_xchg(lkst.current_maskset_id, LKST_MASKSET_ID_RNOTHING);
+}
+
+
+/*********************************************************************
+ * evhandler primitive functions
+ *********************************************************************/
+
+/*
+ * function lkst_evhandlerprim_recid_inc
+ * A primitive part of an Event-handler. This returns ID of the newest 
+ * event record.
+ * 
+ *  Arguments
+ *    NONE
+ *
+ *  returns
+ *    recid:		ID of the newest event record.
+ * 
+ */
+static __inline__ int lkst_evhandlerprim_recid_inc_inline(void)
+{
+	return (lkst.cpu_recid[LKST_CPU_RECID_SIZE*smp_processor_id()]++);
+}
+int lkst_evhandlerprim_recid_inc()
+{
+	return (lkst_evhandlerprim_recid_inc_inline());
+}
+
+/*
+ * function lkst_evhandlerprim_select_buffer_cpu
+ * A primitive part of an Event-handler. This returns address of a buffer 
+ * to write on a specified CPU.
+ * 
+ *  Arguments
+ *    cpu {IN}:	num of CPU
+ *
+ *  returns
+ *    bufferp: address of a buffer to write.
+ * 
+ */
+static __inline__ struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer_cpu_inline(int cpu)
+{
+	lkst_buffer_id buffer_id;
+	struct lkst_event_buffer *bufferp;
+
+	buffer_id =lkst.current_buffer_id[cpu];
+
+	if (buffer_id > LKST_BUFFER_ID_MAX)
+		buffer_id = 0;  /* buffer_id:0 is static, always exists.*/
+	if (!LKST_POINTER_VERIFY(lkst.buffer_table[buffer_id].bufferp, bufferp))
+		bufferp = lkst.buffer_table[0].bufferp;
+
+	return (bufferp);
+}
+
+struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer_cpu(int cpu)
+{
+	return (lkst_evhandlerprim_select_buffer_cpu_inline(cpu));
+}
+
+
+/*
+ * function lkst_evhandlerprim_select_buffer
+ * A primitive part of an Event-handler. This returns address of a buffer 
+ * to write.
+ * 
+ *  Arguments
+ *    NONE
+ *
+ *  returns
+ *    buffer: address of a buffer to write.
+ * 
+ */
+static __inline__ struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer_inline(void)
+{
+	return (lkst_evhandlerprim_select_buffer_cpu_inline(smp_processor_id()));
+}
+struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer(void)
+{
+	return (lkst_evhandlerprim_select_buffer_inline());
+}
+
+
+/*
+ * function lkst_evhandlerprim_select_buffer_id
+ * A primitive part of an Event-handler. This returns address of specified 
+ * buffer to write.
+ * 
+ *  Arguments
+ *    id {IN}:	buffer id.
+ *
+ *  returns
+ *    bufferp: address of a buffer to write.
+ * 
+ */
+static __inline__ struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer_id_inline(lkst_buffer_id id)
+{
+	struct lkst_event_buffer *bufferp;
+
+	if (id > LKST_BUFFER_ID_MAX)
+		id = 0;  /* id:0 is static, always exists.*/
+	if (!LKST_POINTER_VERIFY(lkst.buffer_table[id].bufferp, bufferp))
+		bufferp = lkst.buffer_table[0].bufferp;
+
+	return (bufferp);
+}
+struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer_id(lkst_buffer_id id)
+{
+	return (lkst_evhandlerprim_select_buffer_id_inline(id));
+}
+
+
+/*
+ * function lkst_evhandlerprim_get_write_entry_inline
+ * A primitive part of an Event-handler. This check current_buffer
+ * and increase write-pointer of event buffer and return address of
+ * entry of event buffer to write. 
+ * 
+ *  Arguments
+ *    event_type:	event type
+ *
+ *  returns
+ *    event_entry_p:	address of entry to write.
+ *      NULL		found no entry to write.
+ */
+static __inline__ struct lkst_event_record
+*lkst_evhandlerprim_get_write_entry_inline(int event_type)
+{
+	struct lkst_event_buffer *buffer;
+	struct lkst_event_record *event_entry_p;
+
+	buffer = lkst_evhandlerprim_select_buffer_inline();
+	
+	event_entry_p =
+		lkst_evhandlerprim_entry_next(buffer, event_type);
+
+	return (event_entry_p);
+}
+struct lkst_event_record
+*lkst_evhandlerprim_get_write_entry(int event_type)
+{
+	return (lkst_evhandlerprim_get_write_entry_inline(event_type));
+}
+
+/*
+ * function lkst_evhandlerprim_getw_buffer_cpu_inline
+ * A primitive part of an Event-handler. This marks for buffer writing,
+ * and returns address of a buffer to write on a specified CPU.
+ * 
+ *  Arguments
+ *    cpu {IN}:	num of CPU
+ *
+ *  returns
+ *    buffer: address of a buffer to write.
+ *
+ */
+static __inline__ struct lkst_event_buffer
+*lkst_evhandlerprim_getw_buffer_cpu_inline(int cpu)
+{
+	struct lkst_event_buffer *buffer;
+
+	buffer = lkst_evhandlerprim_select_buffer_cpu_inline(cpu);
+
+	return buffer;
+}
+struct lkst_event_buffer *lkst_evhandlerprim_getw_buffer_cpu(int cpu)
+{
+	return (lkst_evhandlerprim_getw_buffer_cpu_inline(cpu));
+}
+
+/*
+ * function lkst_evhandlerprim_getw_buffer_inline
+ * A primitive part of an Event-handler. This marks for buffer writing,
+ * and returns address of a buffer to write on a CPU correspond to the event.
+ * This function is obsoleted because racing between buffer deletion and buffer
+ * writing is resolved by using "lkst.refcnt".
+ * 
+ *  Arguments
+ *    NONE
+ *
+ *  returns
+ *    buffer: address of a buffer to write.
+ *
+ */
+static __inline__ struct lkst_event_buffer
+*lkst_evhandlerprim_getw_buffer_inline(void)
+{
+	struct lkst_event_buffer *buffer;
+
+	buffer = lkst_evhandlerprim_select_buffer_cpu_inline(smp_processor_id());
+
+	return buffer;
+}
+struct lkst_event_buffer *lkst_evhandlerprim_getw_buffer(void)
+{
+	return (lkst_evhandlerprim_getw_buffer_inline());
+}
+
+/*
+ * function lkst_evhandlerprim_putw_buffer_inline
+ * A primitive part of an Event-handler. This removes a mark of buffer writing
+ * This function is obsoleted because racing between buffer deletion and buffer
+ * writing is resolved by using "lkst.refcnt".
+ *
+ *  Arguments
+ *    buffer: address of a buffer which has a mark of writing.
+ *
+ *  returns
+ *    NONE
+ *
+ */
+static __inline__ void lkst_evhandlerprim_putw_buffer_inline(
+		       struct lkst_event_buffer *buffer)
+{
+}
+void lkst_evhandlerprim_putw_buffer(struct lkst_event_buffer *buffer)
+{
+	lkst_evhandlerprim_putw_buffer_inline(buffer);
+}
+
+
+/*
+ * function lkst_evhandlerprim_entry_log_l2_inline
+ * A primitive part of an Event-handler. This write an event log to 
+ * a currently selected buffer correspond to a cpu on which the event
+ * has occurred.
+ * 
+ *  Arguments
+ *    event_type {IN}:	corresponding event type.
+ *    arg1-4 {IN}:	arguments acquired at a trace point
+ *
+ *  returns
+ *    NONE
+ */
+static __inline__ void
+lkst_evhandlerprim_entry_log_l2_inline(int event_type,
+				       lkst_arg_t arg1, lkst_arg_t arg2,
+				       lkst_arg_t arg3, lkst_arg_t arg4)
+{
+	struct lkst_event_buffer *buffer;
+	struct lkst_event_record *event_entry_p;
+	unsigned long flags;
+	__volatile__ int recid;
+
+	LKST_CLI(flags);
+
+	buffer = lkst_evhandlerprim_getw_buffer_inline();
+
+	recid = lkst_evhandlerprim_recid_inc_inline();
+	event_entry_p = lkst_evhandlerprim_entry_next(buffer, event_type);
+
+	if (event_entry_p)
+		lkst_evhandlerprim_entry_log_l1(event_entry_p, recid,
+						event_type, arg1, arg2, arg3, arg4);
+
+	lkst_evhandlerprim_putw_buffer_inline(buffer);
+
+	LKST_STI(flags);
+}
+void lkst_evhandlerprim_entry_log_l2(int event_type,
+				     lkst_arg_t arg1, lkst_arg_t arg2,
+				     lkst_arg_t arg3, lkst_arg_t arg4)
+{
+	lkst_evhandlerprim_entry_log_l2_inline(event_type,
+					       arg1, arg2, arg3, arg4);
+}
+
+
+/*
+ * function lkst_evhandlerprim_buffer_shift_inline
+ * A primitive part of an Event-handler. This primitive
+ * shifts buffer in the chain of specified cpu.
+ * This primitive is for LKST internal use.
+ * 
+ *  Arguments
+ *    cpu {IN}:	cpu id the buffer chain bound.
+ *
+ *  returns
+ *    ret: 	error code (private).
+ */
+
+static __inline__ int
+lkst_evhandlerprim_buffer_shift_inline(int cpu)
+{
+	struct lkst_event_buffer *buffer, *next_buffer;
+	lkst_buffer_id buffer_id;
+	unsigned long flags;
+	int	ret = LKST_BUFFER_SHIFT_ERRNO_SUCCESS;
+
+	if (cpu >= smp_num_cpus || cpu < 0) {
+		ret = LKST_BUFFER_SHIFT_ERRNO_ECPU;
+		return ret;
+	}
+
+	LKST_CLI(flags);
+	atomic_inc(&(lkst.refcnt));
+
+	buffer_id = lkst.current_buffer_id[cpu];
+	if (!((buffer_id <= LKST_BUFFER_ID_MAX) &&
+	    (LKST_POINTER_VERIFY(lkst.buffer_table[buffer_id].bufferp, buffer)))) {
+
+		ret = LKST_BUFFER_SHIFT_ERRNO_ECBUF;
+		atomic_dec(&(lkst.refcnt));
+		LKST_STI(flags);
+		return ret;
+	}
+
+	buffer_id = buffer->next;
+	if (!((buffer_id <= LKST_BUFFER_ID_MAX) &&
+	    (LKST_POINTER_VERIFY(lkst.buffer_table[buffer_id].bufferp, next_buffer)))) {
+		ret = LKST_BUFFER_SHIFT_ERRNO_ENBUF;
+		atomic_dec(&(lkst.refcnt));
+		LKST_STI(flags);
+		return ret;
+	}
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_BUFF_SHIFT,
+		       LKST_ARG32(buffer->id, 0),
+		       LKST_ARG32(next_buffer->id, 0),
+		       LKST_ARG32(buffer, 0), LKST_ARG32(next_buffer,0));
+
+	/* increment next buffer write count */
+	atomic_inc(&(next_buffer->wcnt));
+
+	/* move write pointer */
+	atomic_set(&(next_buffer->writep), LKST_BUFFER_HEADSPACE);
+
+	/* change current buffer */
+	buffer_id = lkst.current_buffer_id[cpu] = next_buffer->id;
+
+	/* increment previous buffer write count */
+	atomic_inc(&(buffer->wcnt));
+
+#if DEBUG
+	/* Reconfirm this buffer is not been deleting */
+	if (!LKST_POINTER_VERIFY(lkst.buffer_table[buffer_id].bufferp, next_buffer)) {
+		ret = LKST_BUFFER_SHIFT_ERRNO_EBUFC;
+
+			/* Restore current buffer id. */
+		lkst.current_buffer_id[cpu] = buffer->id;
+
+		atomic_dec(&(lkst.refcnt));
+		LKST_STI(flags);
+		return ret;
+	}
+#endif /* DEBUG */
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_BUFF_SHIFT,
+		       LKST_ARG32(buffer->id, 0),
+		       LKST_ARG32(next_buffer->id, 0),
+		       LKST_ARG32(buffer, 0), LKST_ARG32(next_buffer,0));
+
+	atomic_dec(&(lkst.refcnt));
+	LKST_STI(flags);
+	return (LKST_BUFFER_SHIFT_ERRNO_SUCCESS);
+}
+
+
+/*
+ * function lkst_evhandlerprim_maskset_xchg_inline
+ * A primitive part of an Event-handler. This primitive
+ * change current selected maskset to a specified id.
+ * This primitive is for LKST internal use.
+ * 
+ *  Arguments
+ *    id {IN}:	An id of a maskset to be selected next.
+ *
+ *  returns
+ *    ret: 	error code (private).
+ */
+
+static __inline__ int
+lkst_evhandlerprim_maskset_xchg_inline(lkst_maskset_id * id, int xchg_hook)
+{
+	unsigned long flags;
+	int	ret = LKST_MASKSET_XCHG_ERRNO_SUCCESS;
+	lkst_maskset_id old_id = lkst.current_maskset_id, new_id = *id;
+	volatile lkst_maskset *old_maskset = NULL, *new_maskset = NULL;
+
+	LKST_CLI(flags);
+
+	/* Verify old maskset pointer. */
+	if (LKST_POINTER_VERIFY(lkst.current_masksetp, old_maskset)) {
+		/* Verify old maskset id. */
+		if (old_maskset != lkst.maskset_table[old_id].masksetp) {
+			ret = LKST_MASKSET_XCHG_ERRNO_WCPT;
+			old_id = LKST_MASKSET_ID_RDEFAULT;
+		} else {
+			if (old_id > LKST_MASKSET_ID_MAX) {
+				ret = LKST_MASKSET_XCHG_ERRNO_WCID;
+				old_id = LKST_MASKSET_ID_RDEFAULT;
+			}
+		}
+	} else {
+		ret = LKST_MASKSET_XCHG_ERRNO_WCPT;
+		old_id = LKST_MASKSET_ID_RDEFAULT;
+	}
+	/* if old maskset has not been initialized, return as error. */
+	if (!LKST_POINTER_VERIFY
+	    (lkst.maskset_table[old_id].masksetp, old_maskset)) {
+		ret = LKST_MASKSET_XCHG_ERRNO_ECPT;
+		LKST_STI(flags);
+		return ret;
+	}
+
+	if (new_id > LKST_MASKSET_ID_MAX) {
+		/* Verify new maskset id. */
+		ret = LKST_MASKSET_XCHG_ERRNO_ENID;
+		LKST_STI(flags);
+		return ret;
+	}
+	/* if new maskset has not been initialized,
+	   return as error. */
+	if (!LKST_POINTER_VERIFY
+	    (lkst.maskset_table[new_id].masksetp, new_maskset)) {
+		ret = LKST_MASKSET_XCHG_ERRNO_ENPT;
+		LKST_STI(flags);
+		return ret;
+	}
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_MSET_XCHG,
+		       LKST_ARG32(old_id, 0), LKST_ARG32(new_id, 0),
+		       LKST_ARG32(old_maskset,0), LKST_ARG32(new_maskset, 0));
+
+	LKST_MASKSET_SET_CURRENT(new_id);
+
+	*id = old_id;
+
+	if (xchg_hook)
+		lkst_hook_maskset_xchg(new_id, old_id);
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_MSET_XCHG,
+		       LKST_ARG32(old_id, 0), LKST_ARG32(new_id, 0),
+		       LKST_ARG32(old_maskset,0), LKST_ARG32(new_maskset, 0));
+
+	LKST_STI(flags);
+	return ret;
+}
+
+
+/*
+ * function lkst_evhandlerprim_daemon_wakeup_inline
+ * A primitive part of an Event-handler. This awake a daemon process which
+ * is waiting to read a specified buffer list.
+ *
+ *  Arguments
+ *    cpu: cpu number coressponding to a buffer list..
+ *
+ *  returns
+ *    NONE
+ *
+ */
+static __inline__ void lkst_evhandlerprim_daemon_wakeup_inline(int cpu)
+{
+	if (cpu < smp_num_cpus && cpu >= 0) 
+		wake_up_interruptible(&lkst.buffer_wq[cpu]);
+}
+void lkst_evhandlerprim_daemon_wakeup(int cpu)
+{
+	lkst_evhandlerprim_daemon_wakeup_inline(cpu);
+}
+
+/*********************************************************************
+ * Event handle functions (embeded)
+ *********************************************************************/
+
+/* default event handler function */
+void lkst_evhandler_default(void *phookrec, int event_type,
+			    lkst_arg_t arg1,
+			    lkst_arg_t arg2,
+			    lkst_arg_t arg3, lkst_arg_t arg4)
+{
+	lkst_evhandlerprim_entry_log_l2_inline(event_type,
+					       arg1, arg2, arg3, arg4);
+}
+
+/* default event handler control function */
+int lkst_evhandler_default_ctrl(void *buf, size_t bufsize)
+{
+	return 0;
+}
+
+
+/* Event handler for buffer shifting */
+void lkst_evhandler_buffer_shift(void *phookrec, int event_type,
+				 lkst_arg_t arg1,
+				 lkst_arg_t arg2,
+				 lkst_arg_t arg3,
+				 lkst_arg_t arg4)
+{
+	int	cpu = (int)arg1;
+	lkst_buffer_id 	next = (lkst_buffer_id)arg2;
+
+	if (next != LKST_BUFFER_ID_VOID)
+		(void)lkst_evhandlerprim_buffer_shift_inline(cpu);
+}
+
+
+/* Event handler for maskset exchanging */
+void lkst_evhandler_maskset_xchg(void *phookrec, int event_type,
+				 lkst_arg_t arg1,
+				 lkst_arg_t arg2,
+				 lkst_arg_t arg3,
+				 lkst_arg_t arg4)
+{
+	lkst_maskset_id id = (int) arg1;
+
+	(void) lkst_evhandlerprim_maskset_xchg_inline(&id, 0);
+}
+
+
+/* Event handler for shifting buffer and awaking daemon process */
+void lkst_evhandler_buffer_shift_dw(void *phookrec, int event_type,
+				    lkst_arg_t arg1,
+				    lkst_arg_t arg2,
+				    lkst_arg_t arg3,
+				    lkst_arg_t arg4)
+{
+	int cpu = (int) arg1;
+	lkst_buffer_id 	next = (lkst_buffer_id) arg2;
+
+	if (next != LKST_BUFFER_ID_VOID)
+		(void) lkst_evhandlerprim_buffer_shift_inline(cpu);
+
+	lkst_evhandlerprim_daemon_wakeup_inline(cpu);
+}
+
+#if DEBUG
+/* 
+ * event-handler-function lkst_evhandler_exception
+ *
+ * This event handler is used for exception event.
+ * It can record multiple exception events, the first event is
+ * written to currently selected buffer, and after second events are
+ * written to stage0 buffer.
+ *
+ * This event handler is used as not to crush linux kernel because of
+ * occurring multiple exception event.
+ * 
+ * "exhandler_addr" is an exception handler address.
+ *
+ */
+void lkst_evhandler_exception(void *phookrec,
+			      int event_type,
+			      lkst_arg_t arg1,
+			      lkst_arg_t arg2,
+			      lkst_arg_t arg3,
+			      lkst_arg_t arg4)
+{
+	static lkst_arg_t exhandler_addr = 0;
+	int first = 0;
+	struct lkst_event_buffer *buffer = NULL;
+	struct lkst_event_record *event_entry_p;
+	unsigned long flags;
+	__volatile__ int recid;
+
+	LKST_CLI(flags);
+
+	/* exception handler address check */
+	if (exhandler_addr != arg1) {
+		first = 1;
+		exhandler_addr = arg1;
+		buffer = lkst_evhandlerprim_getw_buffer_inline();
+	} else {
+		/* get stage0 buffer pointer */
+		buffer = lkst_evhandlerprim_select_buffer_id_inline(0);
+	}
+
+	recid = lkst_evhandlerprim_recid_inc_inline();
+	event_entry_p = lkst_evhandlerprim_entry_next(buffer, event_type);
+
+	if (event_entry_p)
+		lkst_evhandlerprim_entry_log_l1(event_entry_p, recid,
+						event_type, arg1, arg2, arg3, arg4);
+
+	lkst_evhandlerprim_putw_buffer_inline(buffer);
+
+	if (first) {
+		first = 0;
+		/* clear exception handler address */
+		exhandler_addr = 0;
+	}
+
+	LKST_STI(flags);
+
+	return;
+}
+#endif /* DEBUG */
+
+/*********************************************************************
+ * Lkst core functions
+ *********************************************************************/
+/*
+ * This checks read mode of a specified buffer list.
+ * If the current process is set to read the buffer list,
+ * it returns 0. If not, it returns 1.
+ * When the process is not set, that is not allowed to 
+ * read, seek, create, delete buffers of the buffer list.
+ */
+static __inline__ int lkst_buffer_rmod_check(int cpu)
+{
+	if (lkst.buffer_owner[cpu] != current->pid) {
+		return (lkst.buffer_owner[cpu] != (PID_MAX + 1));
+	}
+	return (0);
+}
+
+
+static __inline__ int lkst_trc_status_core(struct lkst_status_param *param)
+{
+	int i;
+	lkst_maskset *maskset;
+	lkst_evhandler_func evhandler;
+	struct lkst_event_buffer *buffer;
+
+	/* !NOTE!: please check (param != NULL) before calling this.*/
+	param->current_maskset_id = lkst.current_maskset_id;
+
+	for(i = 0; i < LKST_CPU_MAX; i++)
+		param->current_buffer_id[i] = lkst.current_buffer_id[i];
+
+	param->maskset_num = 0;
+	for(i = 0; i < LKST_MASKSET_TBL_MAX; i++)
+		if (LKST_POINTER_VERIFY_STRICT(lkst.maskset_table[i].masksetp, maskset))
+			param->maskset_num++;
+
+	param->evhandler_num = 0;
+	for(i = 0; i < LKST_EVHANDLER_TBL_MAX; i++)
+		if (LKST_POINTER_VERIFY_STRICT(lkst.evhandler_table[i].evhandler, evhandler))
+			param->evhandler_num++;
+
+	param->buffer_num = 0;
+	for(i = 0; i < LKST_BUFFER_TBL_MAX; i++)
+		if (LKST_POINTER_VERIFY_STRICT(lkst.buffer_table[i].bufferp, buffer))
+			param->buffer_num++;
+
+	return 0;
+}
+
+/* lkst_trc_start* and lkst_trc_stop* functions are obsolete.*/
+static __inline__ int lkst_trc_start_core(void)
+{
+	lkst_maskset *maskset;
+	lkst_maskset_id current_id;
+
+	spin_lock(&lkst_status_lock);
+
+	if (lkst.maskset_id_saved > LKST_MASKSET_ID_MAX) {
+		DPRINTK("Save maskset ID=%d is invalid!\n", lkst.maskset_id_saved);
+	        lkst.maskset_id_saved = LKST_MASKSET_ID_RDEFAULT;
+	}
+
+	if (!LKST_POINTER_VERIFY(lkst.maskset_table[lkst.maskset_id_saved].masksetp, maskset)) {
+		DPRINTK("Saved maskset ID=%d has already been deleted!\n", lkst.maskset_id_saved);
+		lkst.maskset_id_saved = LKST_MASKSET_ID_RDEFAULT;
+	}
+
+	current_id = lkst.current_maskset_id;
+	if (current_id != lkst.maskset_id_saved){
+		LKST_MASKSET_SET_CURRENT(lkst.maskset_id_saved);
+		lkst_hook_maskset_xchg(lkst.current_maskset_id, current_id);
+	}
+
+	spin_unlock(&lkst_status_lock);
+
+	return (0);
+}
+
+
+static __inline__ int lkst_trc_stop_core(void)
+{
+	spin_lock(&lkst_status_lock);
+
+	lkst.maskset_id_saved = lkst.current_maskset_id;
+
+	lkst_hook_maskset_xchg(LKST_MASKSET_ID_RNOTHING, lkst.current_maskset_id);
+	LKST_MASKSET_SET_CURRENT(LKST_MASKSET_ID_RNOTHING);
+
+	spin_unlock(&lkst_status_lock);
+
+	return (0);
+}
+
+static __inline__ int lkst_maskset_read_core(struct lkst_maskset_param *param)
+{
+	int i;
+	lkst_maskset *maskset;
+	struct lkst_maskset_entry *entry;
+	lkst_evhandler_id id;
+	size_t size;
+
+	/* !NOTE!: please check (param != NULL) before calling this.*/
+	size = param->maskset_size;
+
+	if (param->id == LKST_MASKSET_ID_VOID)
+		param->id = lkst.current_maskset_id;
+
+	if (param->id > LKST_MASKSET_ID_MAX) {
+		DPRINTK("Invalid maskset ID=%d\n", param->id);
+		return -EINVAL;
+	}
+
+	atomic_inc(&(lkst.refcnt));
+
+	if (!LKST_POINTER_VERIFY
+	    (lkst.maskset_table[param->id].masksetp, maskset)) {
+		DPRINTK("Maskset(ID=%d) does not exist!\n", param->id);
+		atomic_dec(&(lkst.refcnt));
+		return -EINVAL;
+	}
+
+	entry = param->maskset->entry;
+	param->maskset->len = LKST_MASKSET_TABLE_LEN_MAX;
+
+        size -= LKST_MASKSET_SIZE(0);
+
+	for (i = 0; i < LKST_MASKSET_TABLE_LEN_MAX; i++) {
+		id = LKST_MASKSET_QUERY_EVHANDLER_ID(maskset, i);
+		entry->event_type = i;
+		entry->id = id;
+                size -= sizeof(struct lkst_maskset_entry);
+                if (size < sizeof(struct lkst_maskset_entry)){
+			param->maskset->len = i + 1;
+			break;
+                }
+		entry++;
+	}
+
+	strncpy(param->maskset->name, lkst.maskset_table[param->id].name, (size_t) LKST_MASKSET_NAME_LEN);
+	param->maskset->name[LKST_MASKSET_NAME_LEN - 1] = '\0';
+
+	atomic_dec(&(lkst.refcnt));
+
+	return 0;
+}
+
+
+static __inline__ int lkst_maskset_write_core(struct lkst_maskset_param *param)
+{
+	int i;
+	int type;
+	lkst_evhandler_id id;
+	volatile lkst_maskset *maskset;
+	lkst_evhandler_func evhandler;
+	int lock = 0;
+	int wakeup_daemon = 0;
+
+	/* !NOTE!: please check (param != NULL) before calling this.*/
+	if (param->id == LKST_MASKSET_ID_VOID) {
+		/* search empty entry */
+		for (i = 0; i < LKST_MASKSET_TBL_MAX; i++) {
+			if (!LKST_POINTER_VERIFY
+			    (lkst.maskset_table[i].masksetp, maskset))
+				break;
+		}
+		if (i == LKST_MASKSET_TBL_MAX) {
+			DPRINTK("Cannot register maskset any more!\n", "");
+			return -EBUSY;
+		}
+		param->id = i;
+	}
+
+	if (param->id <= LKST_MASKSET_ID_RDEFAULT ||
+	    param->id > LKST_MASKSET_ID_MAX) {
+		DPRINTK("Invalid number of maskset ID=%d\n", param->id);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < param->maskset->len; i++ ) {
+		type = param->maskset->entry[i].event_type;
+		id = param->maskset->entry[i].id;
+
+		if (type > LKST_ETYPE_MAX || type < 0) {
+			DPRINTK("Invalid event_type=%d\n", type);
+			return -EINVAL;
+		}
+
+		if (id > LKST_EVHANDLER_ID_MAX &&
+		    id != LKST_EVHANDLER_ID_VOID) {
+			DPRINTK("Invalid handler ID=%d\n", id);
+			return -EINVAL;
+		}
+		if (!LKST_POINTER_VERIFY(lkst.evhandler_table[id].evhandler, evhandler) && id != LKST_EVHANDLER_ID_VOID) {
+	    		DPRINTK("Handler(ID=%d) does not exist!\n", id);
+			return -EINVAL;
+		}
+
+ 		/* Check whether events concerned with spinlocks
+		   are recorded. Event type of these events 
+		   should be 0x8*.				  */
+		if ((type >> 4) == (LKST_ETYPE_LK_SPINLOCK >> 4) &&
+		    id != LKST_EVHANDLER_ID_VOID) 
+			lock = 1;
+
+		if (type == LKST_ETYPE_LKST_BUFF_OVFLOW &&
+		    id == LKST_EVHANDLER_ID_BUFFER_SHIFT_DW)
+			wakeup_daemon = 1;
+	}
+
+	if (lock && wakeup_daemon) {
+		DPRINTK("Cannot use shift and wakeup event handler for buffer overflow event when recording lock events!\n", "");
+		return -EINVAL;
+	}		
+
+	atomic_inc(&(lkst.refcnt));
+
+	if (lkst.maskset_table[param->id].masksetp == NULL) {
+		/* new maskset-table allocate */
+		maskset = vmalloc(sizeof(lkst_evhandler_id) * (LKST_ETYPE_MAX + 1));
+		if (maskset == NULL) {
+			DPRINTK("Cannot allocate kernel memory!\n", "");
+			atomic_dec(&(lkst.refcnt));
+			return -ENOMEM;
+		}
+
+		if (!LKST_LIMIT_ADDRESS_CHECK(maskset, sizeof(lkst_evhandler_id) * (LKST_ETYPE_MAX + 1), lkst.limit_addr)) {
+			DPRINTK("Cannot allocate maskset area! Aloocation limit address:0x%p, new maskset needs to 0x%p\n", lkst.limit_addr, (void *) ((char *) maskset + sizeof(lkst_evhandler_id) * (LKST_ETYPE_MAX + 1)));
+			vfree((lkst_maskset *) maskset);
+			atomic_dec(&(lkst.refcnt));
+			return -ENOMEM;
+		}
+
+		/* init */
+		for (i = 0; i <= LKST_ETYPE_MAX; i++)
+			LKST_MASKSET_SET_EVHANDLER_ID(maskset, i, LKST_EVHANDLER_ID_VOID);
+
+		LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table, param->id, 
+					     param->maskset->name, maskset);
+
+	} else {
+
+		/* table will be overwritten */
+		if (!LKST_POINTER_VERIFY
+		    (lkst.maskset_table[param->id].masksetp, maskset)){
+			DPRINTK("Maskset(ID=%d) is collapsed!\n", param->id);
+			atomic_dec(&(lkst.refcnt));
+			return -EBUSY;
+		}
+
+		strncpy(lkst.maskset_table[param->id].name,
+			param->maskset->name,
+			(size_t) LKST_MASKSET_NAME_LEN);
+		lkst.maskset_table[param->id].name[LKST_MASKSET_NAME_LEN - 1] = '\0';
+	}
+
+	if(param->id == lkst.current_maskset_id)
+	{
+		for (i = 0; i < param->maskset->len; i++){
+			lkst_event_type etype = param->maskset->entry[i].event_type;
+			if((LKST_MASKSET_QUERY_EVHANDLER_ID(maskset, etype) != param->maskset->entry[i].id)&&
+			   (etype < LKST_MASKSET_TBL_MAX))
+			{
+				lkst_hook_exit_xchg(etype, param->maskset->entry[i].id, LKST_MASKSET_QUERY_EVHANDLER_ID(maskset, etype));
+			}
+		}
+	}
+
+	/* main */
+	for (i = 0; i < param->maskset->len; i++)
+		LKST_MASKSET_SET_EVHANDLER_ID(maskset, param->maskset->entry[i].event_type, param->maskset->entry[i].id);
+
+	atomic_dec(&(lkst.refcnt));
+
+	return 0;
+}
+
+
+static __inline__ int lkst_maskset_xchg_core(lkst_maskset_id * id)
+{
+	int	ret;
+	lkst_maskset_id old_id;
+
+	/* !NOTE!: please check (id != NULL) before calling this.*/
+	old_id= *id;
+
+	ret = lkst_evhandlerprim_maskset_xchg_inline(id, 1);
+
+	switch (ret) {
+	case LKST_MASKSET_XCHG_ERRNO_SUCCESS:
+		return 0;
+	case LKST_MASKSET_XCHG_ERRNO_WCPT:
+		DPRINTK("Current maskset(ID=%d) is collapsed!\n", old_id);
+		return 0;
+	case LKST_MASKSET_XCHG_ERRNO_WCID:
+		DPRINTK("Invalid ID=%d of current maskset!\n", old_id);
+		return 0;
+	case LKST_MASKSET_XCHG_ERRNO_ECPT:
+		DPRINTK("Current maskset(id=%d) is collapsed!\n", old_id);
+		return -EBUSY;
+	case LKST_MASKSET_XCHG_ERRNO_ENID:
+		DPRINTK("Invalid maskset ID=%d\n", *id);
+		return -EINVAL;
+	case LKST_MASKSET_XCHG_ERRNO_ENPT:
+		DPRINTK("Specified maskset(ID=%d) does not exist!\n", *id);
+		return -EINVAL;
+	case LKST_MASKSET_XCHG_ERRNO_ESTAT:
+		DPRINTK("Cannot change maskset when LKST is not running!\n", "");
+		return -EBUSY;
+	default:
+		DPRINTK("Unknown error occured, old/new maskset ID=%d/%d.\n", old_id, *id);
+		return -EINVAL;
+	}
+}
+
+
+static __inline__ int lkst_maskset_list_core(struct lkst_maskset_listparam *lp)
+{
+	int i, cnt, cnt_max;
+	lkst_maskset *maskset;
+
+	/* !NOTE!: please check (lp != NULL) before calling this.*/
+	if(lp->listent_size < sizeof(struct lkst_maskset_listent) ||
+	   lp->listent_size > LKST_MASKSET_LISTENT_SIZE(LKST_MASKSET_TBL_MAX)) {
+		DPRINTK("Invalid listent_size=%d\n", lp->listent_size);
+		return -EINVAL;
+	}
+
+	cnt = 0;
+	cnt_max = lp->listent_size / sizeof(struct lkst_maskset_listent);
+
+	for (i = 0; i < cnt_max; i++) {
+		lp->listent[i].id = LKST_MASKSET_ID_VOID;
+		lp->listent[i].name[0]='\0';
+		lp->listent[i].len = 0;
+	}
+		
+	for (i = 0; i < LKST_MASKSET_TBL_MAX; i++) {
+		if (LKST_POINTER_VERIFY_STRICT(lkst.maskset_table[i].masksetp, maskset)) {
+
+			lp->listent[cnt].id = i;
+			strcpy(lp->listent[cnt].name, lkst.maskset_table[i].name);
+			
+			lp->listent[cnt].len = LKST_MASKSET_TABLE_LEN_MAX;
+			cnt++;
+			if(cnt > cnt_max)
+				return 0;
+		}
+	}
+
+	lp->current_id = lkst.current_maskset_id;
+
+	return 0;
+}
+
+
+static __inline__ int lkst_maskset_delete_core(lkst_maskset_id id)
+{
+	lkst_maskset *maskset;
+
+	if (id == LKST_MASKSET_ID_RALL ||
+	    id == LKST_MASKSET_ID_RNOTHING ||
+	    id == LKST_MASKSET_ID_RDEFAULT) {
+		DPRINTK("Cannot delete special maskset!\n", "");
+		return -EINVAL;
+	}
+
+	if (id > LKST_MASKSET_ID_MAX) {
+		DPRINTK("Invalid maskset ID=%d\n", id);
+		return -EINVAL;
+	}
+
+	if (id == lkst.current_maskset_id) {
+		DPRINTK("Specified maskset(ID=%d) is currently used!\n", id);
+		return -EBUSY;
+	}
+	
+	/* for obsolete routines:-P */
+	if (id == lkst.maskset_id_saved) {
+		DPRINTK("Specified maskset(ID=%d) is currently saved!\n Change to DEFAULT maskset.", id);
+		lkst.maskset_id_saved = LKST_MASKSET_ID_RDEFAULT;
+	}
+
+	if (!LKST_POINTER_VERIFY
+	    (lkst.maskset_table[id].masksetp, maskset)) {
+		DPRINTK("Maskset(ID=%d) does not exist!\n", id);
+		return -EINVAL;
+	}
+
+	LKST_POINTER_INVALIDATE(lkst.maskset_table[id].masksetp);
+
+			/* Wait until all the event handlers exit. */
+	while (atomic_read(&(lkst.refcnt)));
+
+			/* Reconfirm this maskset is not used currently. */
+	if (id == lkst.current_maskset_id) {
+		DPRINTK("Specified maskset(ID=%d) is currently used!\n", id);
+
+			/* Restore buffer pointer */
+		lkst.maskset_table[id].masksetp = maskset;
+		LKST_POINTER_CHECK_INIT(lkst.maskset_table[id].masksetp);
+
+		return -EBUSY;
+	}
+
+	vfree(maskset);
+
+	return 0;
+}
+
+static __inline__ int 
+lkst_evhandler_list_core(struct lkst_evhandler_listparam *lp)
+{
+	int i, cnt, cnt_max;
+	lkst_evhandler_func evhandler;
+
+	/* !NOTE!: please check (lp != NULL) before calling this.*/
+	if(lp->listent_size < sizeof(struct lkst_evhandler_listent) ||
+	   lp->listent_size > LKST_EVHANDLER_LISTENT_SIZE(LKST_EVHANDLER_TBL_MAX)) {
+		DPRINTK("Invalid listent_size=%d\n", lp->listent_size);
+		return -EINVAL;
+	}
+
+	cnt = 0;
+	cnt_max = lp->listent_size / sizeof(struct lkst_evhandler_listent);
+
+	for (i = 0; i < cnt_max; i++) {
+		lp->listent[i].id = LKST_EVHANDLER_ID_VOID;
+		strcpy(lp->listent[i].name, "");
+	}
+		
+	for (i = 0; i < LKST_EVHANDLER_TBL_MAX; i++) {
+		if (LKST_POINTER_VERIFY(lkst.evhandler_table[i].evhandler, evhandler)) {
+
+			lp->listent[cnt].id = i;
+			strcpy(lp->listent[cnt].name, lkst.evhandler_table[i].name);
+			
+			cnt++;
+			if(cnt > cnt_max)
+				return 0;
+		}
+	}
+
+	return 0;
+}
+
+
+static __inline__ int 
+lkst_evhandler_ctrl_core(struct lkst_evhandler_ctrl_param *evhandler_ctrl_param)
+{
+	lkst_evhandler_id id;
+	lkst_evhandler_ctrl_func evhandler_ctrl;
+
+	id = evhandler_ctrl_param->id;
+	if (id > LKST_EVHANDLER_ID_MAX) {
+		DPRINTK("Invalid handler ID = %d\n", id);
+		return -EINVAL;
+	}
+
+	if (!LKST_POINTER_VERIFY(lkst.evhandler_table[id].evhandler_ctrl,
+				 evhandler_ctrl)) {
+		DPRINTK("Ctrl-function(ID=%d) does not exist!\n", id);
+		return -EINVAL;
+	}
+
+	evhandler_ctrl_param->ret = (*evhandler_ctrl) (evhandler_ctrl_param->buf,
+						       evhandler_ctrl_param->bufsize);
+
+
+	return 0;
+}
+
+/*
+ * lkst_write_to_log
+ * return value : recid
+ * write down event-buffer entry to log-buffer.
+ */
+static void lkst_write_to_log(struct lkst_event_record *entry,
+			      struct lkst_log_record *log)
+{
+	struct task_struct *task = NULL;
+	static uid_t uid;
+	static gid_t gid;
+	static pid_t pid = PID_MAX + 1;
+	static pid_t pgrp;
+
+	/* Is the current (logged) pid same as the last?*/
+	if (pid != entry->log_pid) {
+		/*Different! hum, then, we have to check that uid, gid and pgrp.*/
+		pid = entry->log_pid;
+		read_lock(&tasklist_lock);
+		task = find_task_by_pid(pid);
+		if (task == NULL) {
+		  /* write dummy value if task_struct was already deleted */
+			uid = -1;	// TODO: write after
+			gid = -1;	// TODO: write after
+			pgrp = -1;	// TODO: write after
+		} else {
+			uid = task->uid;
+			gid = task->gid;
+			pgrp = task->pgrp;
+		}
+		read_unlock(&tasklist_lock);
+	}
+
+	log->posix.log_magic = 0x76758384;	// TODO: value
+	log->posix.log_size = sizeof(lkst_arg_t) * 4;
+	log->posix.log_format = PXLOG_BINARY;
+	log->posix.log_facility = LOG_KERN;
+	log->posix.log_severity = LOG_DEBUG;
+	log->posix.log_recid = entry->log_recid;
+	log->posix.log_event_type = entry->log_event_type;
+	log->posix.log_pid = pid;
+	log->posix.log_uid = uid;
+	log->posix.log_gid = gid;
+	log->posix.log_pgrp = pgrp;
+	log->posix.log_flags = 0;
+	log->posix.log_time.tv_sec = (time_t) ((entry->log_time) >> 32);
+	log->posix.log_time.tv_nsec = (unsigned long) entry->log_time;
+	log->posix.log_thread = -1;		// TODO: write after
+	log->log_arg1 = entry->log_arg1;
+	log->log_arg2 = entry->log_arg2;
+	log->log_arg3 = entry->log_arg3;
+	log->log_arg4 = entry->log_arg4;
+}
+
+static inline int lkst_buffer_read_core(struct lkst_log_buffer *lbuffer,
+			unsigned char flag)
+{
+	size_t readp, readp_s, writep;
+	size_t count, rsize, result_readp;
+	size_t log_writep;
+	size_t sizem;
+	int cpu;
+	int wrapped = 0;
+	int current_f;
+	int ring;
+	struct lkst_event_buffer *buffer=NULL;
+	struct lkst_event_record *entry, *prev_entry;
+	struct lkst_log_record record, *record_p;
+	lkst_buffer_id id;
+	int prev_recid;
+	int rcnt, rwdiff;
+
+	/* !NOTE!: please check (lbuffer != NULL) before calling.*/
+	count = lbuffer->read_size;
+	lbuffer->result_read_size = 0;
+
+	if (lbuffer->id > LKST_BUFFER_ID_MAX) {
+		DPRINTK("Invalid buffer ID = %d\n", lbuffer->id);
+		return -EINVAL;
+	}
+
+	id = lbuffer->id;
+
+	log_writep = 0;
+	if (flag)
+		/* Called from lkst_buffer_read_ioctl() or lkst_read() */
+		record_p = &record;
+	else
+		/* Called from lkst_buffer_read() (for module use) */
+		record_p = lbuffer->buffer;
+
+	atomic_inc(&(lkst.refcnt));
+
+#if DEBUG
+retry:
+#endif /* DEBUG */
+
+	if (!LKST_POINTER_VERIFY(lkst.buffer_table[id].bufferp, buffer)) {
+		DPRINTK("Buffer(ID=%d) does not exist!\n", id);
+		atomic_dec(&(lkst.refcnt));
+		/* return with result_read_size = 0. */
+		return -EINVAL;
+	}
+
+	rcnt = atomic_read(&(buffer->rcnt));
+
+	cpu = buffer->cpu;
+
+	ring = lkst.buffer_ring[cpu];
+
+	if ((flag & 0x01) && ring && id != 0) {
+		DPRINTK("Cannot read ring structure buffer!\n", "");
+		atomic_dec(&(lkst.refcnt));
+		/* return with result_read_size = 0. */
+		return -EBUSY;
+	}		
+
+	if (lkst_buffer_rmod_check(cpu)) {
+		DPRINTK("Process(pid=%d) is not set to read this buffer list(cpu=%d).\n", current->pid, cpu);
+		atomic_dec(&(lkst.refcnt));
+		/* return with result_read_size = 0. */
+		return -EBUSY;
+	}		
+
+	sizem = buffer->size - 1;
+
+	/* get buffer time stamp */
+	/* TODO : buffer's timestamp should be modified when lkst_header is modified.*/
+	if (!lkst.cmos_time_flag && buffer->cmos_time_flag) {
+		buffer->xtime.tv_sec = lkst.xtime.tv_sec;
+		buffer->xtime.tv_usec = lkst.xtime.tv_usec;
+		buffer->cmos_time_flag = 0;
+	}
+	lbuffer->tsc = lkst.tsc;
+	lbuffer->xtime.tv_sec = buffer->xtime.tv_sec;
+	lbuffer->xtime.tv_usec = buffer->xtime.tv_usec;
+	lbuffer->cpu_freq = lkst.cpu_freq;
+	lbuffer->buf_ver = lkst.buf_ver;
+	strncpy(lbuffer->arch, lkst.arch, LKST_ARCH_NAME_LEN);
+	lbuffer->endian_big = lkst.endian_big;
+
+	/* exit if count is smaller than the size of one log entry */
+	if (count < sizeof(struct lkst_log_record)) {
+		/* return with result_read_size = 0. */
+		atomic_dec(&(lkst.refcnt));
+		return 0;
+	}
+
+	readp = buffer->readp;
+	current_f = (lkst.current_buffer_id[cpu] == id);
+
+	/* load previous entry of read pointer */
+	(char *) prev_entry = (char *) (buffer->body) +
+		(buffer->last_readp & sizem);
+
+	/* get buffer write pointer */
+	writep = (size_t) (buffer->writep.counter & sizem);
+
+	/* buffer wrap check */
+	if (buffer->last_recid != prev_entry->log_recid) {
+		wrapped = 1;
+		readp = writep;
+		(char *) prev_entry = (char *) (buffer->body) + 
+			((readp - sizeof(struct lkst_event_record)) & sizem);
+	} else if (readp == writep) {
+		/* buffer is empty */
+		/* return with result_read_size = 0. */
+		atomic_dec(&(lkst.refcnt));
+		return 0;
+	}
+
+	/* HEADSPACE read check */
+	if (ring) {
+		rsize = count / sizeof(struct lkst_event_record) *
+			sizeof(struct lkst_log_record);
+
+		result_readp = (rsize + readp) & sizem;
+
+		if (rsize < buffer->size &&
+		    result_readp < LKST_BUFFER_HEADSPACE) {
+			if (rsize > result_readp) {
+				rsize -= result_readp;
+				count -= LKST_BUFFER_SIZE_LOCAL2EXT(result_readp);
+			} else {
+				DPRINTK("Cannot read buffer headspace, please read larger size.\n", "");
+				atomic_dec(&(lkst.refcnt));
+				return -EINVAL;
+			}
+		}
+	}
+
+	/* set read stopper */
+	if (!current_f)
+		readp_s = writep;
+	else 
+		readp_s = readp;
+
+	(char *) entry = (char *) (buffer->body) + (readp & sizem);
+
+#if DEBUG
+		/* Assume no next buffer to read. */
+	id = LKST_BUFFER_ID_VOID;
+#endif /* DEBUG */
+
+	if (wrapped)
+		prev_recid = entry->log_recid;
+	else
+		prev_recid = prev_entry->log_recid;
+
+	while (log_writep + sizeof(struct lkst_log_record) <= count) {
+
+		lkst_write_to_log(entry, record_p);
+		record_p->posix.log_processor = (posix_log_procid_t) cpu;
+
+		/* entry overwritten check */
+		if (record_p->posix.log_recid <= prev_recid) {
+			record_p->log_arg4 = LKST_ARG32(record_p->posix.log_event_type, 0);
+			record_p->posix.log_event_type = LKST_ETYPE_LKST_OVWRTN_REC;
+
+				/* flag & 0x2 :Called from lkst_read() */
+			if (flag & 0x02 && buffer->next != LKST_BUFFER_ID_VOID) { 
+				/* buffer read/write count check */
+				rwdiff = atomic_read(&(buffer->wcnt)) - rcnt;
+				if (rwdiff >= 2) {
+					/* Get next buffer ID */
+					lbuffer->id = buffer->next;
+					break;
+				}
+			}
+
+			if (current_f)
+				wrapped = 1;
+		}
+		    
+		prev_entry = entry;
+		/* update prev_recid */
+		if (prev_recid < prev_entry->log_recid || !ring)
+			prev_recid = prev_entry->log_recid;
+
+		entry++;
+
+		if (flag) {
+			if (copy_to_user((char *) (lbuffer->buffer) + log_writep, &record, sizeof(struct lkst_log_record))) {
+				DPRINTK("Writing fail at user memory address=%p\n", (lbuffer->buffer) + log_writep);
+				break;
+			} 
+		} else
+			record_p++;
+
+		buffer->last_recid = record_p->posix.log_recid;
+		buffer->last_readp = readp & sizem;
+
+		log_writep += sizeof(struct lkst_log_record);
+
+		readp += sizeof(struct lkst_event_record);
+
+		if (readp >= buffer->size) {
+			entry = buffer->body;
+			readp &= sizem;
+		}
+
+                if (current_f && !wrapped) {
+                        writep = atomic_read(&(buffer->writep)) & sizem;
+                        if (readp == writep)
+                                break;
+                }
+
+		if (readp == readp_s) {
+				/* flag & 0x2 :Called from lkst_read() */
+			if ((flag & 0x2) && buffer->next != LKST_BUFFER_ID_VOID) {
+#if DEBUG
+				/* Remember next buffer to chain reading. */
+				id = buffer->next;
+#endif /* DEBUG */
+				/* Get next buffer ID */
+				lbuffer->id = buffer->next;
+			}
+			break;
+		}
+	}
+
+	buffer->readp = readp;
+
+	lbuffer->result_read_size = log_writep;
+#if DEBUG
+	if (id != LKST_BUFFER_ID_VOID) {
+		atomic_dec(&(lkst.refcnt));
+				/* Wait next buffer filled if needed. */
+		atomic_inc(&(lkst.refcnt));
+		goto retry;
+	}
+#endif /* DEBUG */
+
+	atomic_dec(&(lkst.refcnt));
+
+	return 0;
+}
+
+#if DEBUG
+static __inline__ int lkst_buffer_seek_core(struct lkst_buffer_seekparam *bs)
+{
+	struct lkst_event_buffer *buffer;
+	struct lkst_event_record *prev_entry;
+	size_t buff_size, writep, readp;
+	int offset, diff;
+
+	/* !NOTE!: please check (bs != NULL) before calling this.*/
+	if (bs->id > LKST_BUFFER_ID_MAX) {
+		DPRINTK("Invalid buffer ID=%d\n", bs->id);
+		return -EINVAL;
+	}
+
+	offset = bs->offset;
+
+	if (offset % ((int) sizeof(struct lkst_event_record))) {
+		offset -= (offset % ((int) sizeof(struct lkst_event_record)));
+		DPRINTK("Offset must be multiple of buffer entry size(%d), modified to %d\n", sizeof(struct lkst_event_record), offset);
+	}
+
+	spin_lock(&lkst_buffer_lock);
+
+	if (!LKST_POINTER_VERIFY(lkst.buffer_table[bs->id].bufferp, buffer)) {
+		DPRINTK("Buffer(ID=%d) does not exist!\n", bs->id);
+		spin_unlock(&lkst_buffer_lock);
+		return -EINVAL;
+	}
+
+	if (lkst_buffer_rmod_check(buffer->cpu)) {
+		DPRINTK("Process(pid=%d) is not allowed to control this buffer list(cpu=%d).\n", current->pid, buffer->cpu);
+		spin_unlock(&lkst_buffer_lock);
+		return -EBUSY;
+	}		
+
+	buff_size = buffer->size;
+
+	if (offset > (int) buff_size || offset < -((int) buff_size)) {
+		DPRINTK("Invalid offset=%d!\n", offset);
+		spin_unlock(&lkst_buffer_lock);
+		return -EINVAL;
+	}
+
+	readp = buffer->readp;
+
+	(char *) prev_entry = (char *) (buffer->body) + buffer->last_readp;
+
+	/* wrap check */
+	if (buffer->last_recid == prev_entry->log_recid) {
+		/* not wrapped */
+		writep = (atomic_read(&(buffer->writep)) &
+			  (buff_size - 1));
+
+		diff = readp <= writep ?
+			writep - readp : writep + buff_size - readp;
+
+		if (offset >= diff)
+			readp = writep;
+		else if (offset <= (diff - (int) buff_size))
+			readp = (writep + sizeof(struct lkst_event_record))
+				& (buff_size - 1);
+		else
+			readp = (readp + offset) & (buff_size - 1);
+
+		prev_entry = 
+			LKST_BUFFER_PREV_ENTRY(buffer->body, readp, buff_size);
+
+		buffer->last_recid = prev_entry->log_recid;
+	} else {
+		/* wrapped */
+		readp = (readp + offset) & (buff_size - 1);
+	}
+
+	buffer->readp = readp;
+	buffer->last_readp = 
+		(readp - sizeof(struct lkst_event_record)) & (buff_size - 1);
+
+	bs->result_readp = readp;
+
+	spin_unlock(&lkst_buffer_lock);
+
+	return 0;
+}
+#endif /* DEBUG */
+
+static __inline__ int 
+lkst_buffer_create_core_cpu(int cpu,
+			    struct lkst_buffer_param *param)
+{
+	lkst_buffer_id prev_id;
+	struct lkst_event_buffer *buffer, *prev_buffer = NULL, *head_buffer;
+	size_t size;
+	int i;
+
+	/* !NOTE!: please check (param != NULL) before calling this.*/
+	if (param->id == LKST_BUFFER_ID_VOID) {
+		/* search empty entry */
+		for (i = 0; i < LKST_BUFFER_TBL_MAX; i++) {
+			if (!LKST_POINTER_VERIFY
+			    (lkst.buffer_table[i].bufferp, buffer))
+				break;
+		}
+		if (i == LKST_BUFFER_TBL_MAX) {
+			DPRINTK("Cannot create buffer any more!\n", "");
+			return -EBUSY;
+		}
+		param->id = i;
+	}
+
+
+	if (param->id > LKST_BUFFER_ID_MAX) {
+		DPRINTK("Invalid buffer ID = %d\n", param->id);
+		return -EINVAL;
+	}
+
+	if (LKST_POINTER_VERIFY(
+		lkst.buffer_table[param->id].bufferp, buffer)) {
+		DPRINTK("Buffer(ID=%d) already exist!\n", param->id);
+		return -EINVAL;
+	}
+
+	if (param->size < LKST_BUFFER_SIZE_MIN) {
+		DPRINTK("buffer size(=%d) is too small, changed to %d\n", param->size, LKST_BUFFER_SIZE_MIN);
+		param->size = LKST_BUFFER_SIZE_MIN;
+	} else if (param->size > LKST_BUFFER_SIZE_MAX) {
+		DPRINTK("buffer size(=%d) is too large, changed to %d\n", param->size, LKST_BUFFER_SIZE_MAX);
+		param->size = LKST_BUFFER_SIZE_MAX;
+	}
+
+	for (size = LKST_BUFFER_SIZE_MAX; size > param->size; size = size >> 1);
+	if (param->size != size)
+		DPRINTK("Buffer size must be power of 2, changed to %d\n", size);
+
+	param->result_size = size;
+
+	/* create new buffer area */
+	buffer = vmalloc(LKST_BUFFER_AREA_SIZE(size));
+	if (buffer == NULL) {
+		DPRINTK("Cannot allocate kernel memory(size=%d)\n", LKST_BUFFER_AREA_SIZE(size));
+		return -ENOMEM;
+	}
+	if (!LKST_LIMIT_ADDRESS_CHECK(buffer, size, lkst.limit_addr)) {
+		DPRINTK("Cannot allocate buffer area! Aloocation limit address:0x%p, new buffer needs to 0x%p\n", lkst.limit_addr, (void *) ((char *) buffer + size));
+		vfree(buffer);
+		return -ENOMEM;
+	}
+	
+	spin_lock(&lkst_buffer_lock);
+
+			/* Wait until all the event handlers exit. */
+	while (atomic_read(&(lkst.refcnt)));
+
+	/* acquire buffer_tail */
+	prev_id = lkst.buffer_tail[cpu];
+
+	if (prev_id != LKST_BUFFER_ID_VOID) {
+		if (!LKST_POINTER_VERIFY
+		    (lkst.buffer_table[prev_id].bufferp, prev_buffer)) {
+			DPRINTK("Buffer ID=%d of the specified cpu is collapsed! (cannot connect new buffer to the buffer list)\n", prev_id);
+			vfree(buffer);
+			spin_unlock(&lkst_buffer_lock);
+			return -EBUSY;
+		}
+		buffer->next = prev_buffer->next;
+	} else 
+		buffer->next = LKST_BUFFER_ID_VOID;
+
+	if (lkst.buffer_ring[cpu]) {
+		/* This buffer is in ring structure */
+
+		if (!LKST_POINTER_VERIFY
+		    (lkst.buffer_table[buffer->next].bufferp, head_buffer)) {
+			DPRINTK("Buffer ID=%d is collapsed!\n", buffer->next);
+			vfree(buffer);
+			spin_unlock(&lkst_buffer_lock);
+			return -EBUSY;
+		}
+		head_buffer->prev = param->id;
+	}
+
+	buffer->size = size;
+
+	buffer->readp = LKST_BUFFER_HEADSPACE;
+	atomic_set(&(buffer->writep), LKST_BUFFER_HEADSPACE);
+
+	buffer->id = param->id;
+	buffer->prev = prev_id;
+	buffer->cpu = cpu;
+	buffer->last_recid = 0;
+	buffer->last_readp = 
+		(LKST_BUFFER_HEADSPACE - sizeof(struct lkst_event_record)) &
+		(size - 1);
+
+	buffer->cmos_time_flag = lkst.cmos_time_flag;
+	buffer->xtime.tv_sec = lkst.xtime.tv_sec;
+	buffer->xtime.tv_usec = lkst.xtime.tv_usec;
+
+	strncpy(buffer->eyecatcher, "LKBF", 4);
+	buffer->buf_ver = LKST_BUF_VER;
+
+	atomic_set(&(buffer->rcnt), 0);
+	atomic_set(&(buffer->wcnt), 0);
+
+	/* clear recid, event_type */
+	for (i = 0; i < (size / sizeof(struct lkst_event_record)); i++) {
+		(buffer->body + i)->log_recid = 0;
+		(buffer->body + i)->log_event_type = LKST_ETYPE_VOID;
+	}
+
+	/* modify buffer_tail */
+	lkst.buffer_tail[cpu] = param->id;
+
+	/* register to buffer_table */
+	lkst.buffer_table[param->id].bufferp = buffer;
+	LKST_POINTER_CHECK_INIT(lkst.buffer_table[param->id].bufferp);
+
+	/* connect to tail of buffer list of specified cpu */
+	if (prev_id != LKST_BUFFER_ID_VOID)
+		prev_buffer->next = param->id;
+
+	spin_unlock(&lkst_buffer_lock);
+
+	return 0;
+}
+
+
+static __inline__ int lkst_buffer_create_core(struct lkst_buffer_param *param)
+{
+	int cpu, cpu_count = 1;
+	int i;
+	int retval;
+
+	/* !NOTE!: please check (param != NULL) before calling this.*/
+	cpu = param->cpu;
+
+	if (cpu == -1) { /* create buffers for all CPUs */
+		cpu = 0;
+		cpu_count = smp_num_cpus;
+	} else if (cpu >= smp_num_cpus || cpu < 0) {
+		DPRINTK("Invalid CPU number=%d\n", cpu);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cpu_count; i++) {
+		if (param->cpu == -1)
+			param->id = LKST_BUFFER_ID_VOID;
+		if (lkst_buffer_rmod_check(cpu)) {
+			DPRINTK("Process(pid=%d) is not allowed to control this buffer list(cpu=%d).\n", current->pid, cpu);
+			return -EBUSY;
+		}
+		retval = lkst_buffer_create_core_cpu(cpu, param);
+		if (retval)
+			return retval;
+		cpu++;
+	}
+
+	return 0;
+}
+
+
+static __inline__ int lkst_buffer_shift_core(int cpu)
+{
+	int	ret;
+
+	if (lkst.buffer_ring[cpu]) {
+		DPRINTK("Cannot shift ring structure buffer!\n", "");
+		return -EBUSY;
+	}
+
+	if (lkst_buffer_rmod_check(cpu)) {
+		DPRINTK("Process(pid=%d) is not allowed to control this buffer list(cpu=%d).\n", current->pid, cpu);
+		return -EBUSY;
+	}		
+
+	ret = lkst_evhandlerprim_buffer_shift_inline(cpu);
+
+	switch (ret) {
+	case LKST_BUFFER_SHIFT_ERRNO_SUCCESS:
+		return 0;
+	case LKST_BUFFER_SHIFT_ERRNO_ECPU:
+	  	DPRINTK("Invalid CPU number=%d\n", cpu); 
+		return -EINVAL;
+	case LKST_BUFFER_SHIFT_ERRNO_ECBUF:
+		DPRINTK("Current buffer of CPU=%d does not exist!\n", cpu); 
+		return -EBUSY;
+	case LKST_BUFFER_SHIFT_ERRNO_ENBUF:
+		DPRINTK("Next buffer of CPU=%d does not exist!\n", cpu);
+		return -EBUSY;
+	case LKST_BUFFER_SHIFT_ERRNO_EBUFC:
+		DPRINTK("Next buffer of CPU=%d seems to be in deleting!\n", cpu);
+		return -EBUSY;
+	default:
+		DPRINTK("Unknown error occured, CPU=%d.\n", cpu);
+		return -EINVAL;
+	}
+}
+
+
+static __inline__ int lkst_buffer_delete_core(lkst_buffer_id id)
+{
+	struct lkst_event_buffer *buffer, *prev_buffer, *next_buffer;
+
+	if (id == 0) {
+		DPRINTK("Cannot delete buffer of ID=%d\n", id);
+		return -EINVAL;
+	}
+
+	spin_lock(&lkst_buffer_lock);
+
+	if (!LKST_POINTER_VERIFY_STRICT(lkst.buffer_table[id].bufferp, buffer)) {
+		DPRINTK("Buffer(ID=%d) does not exist!\n", id);
+		spin_unlock(&lkst_buffer_lock);
+		return -EINVAL;
+	}
+
+	if (lkst_buffer_rmod_check(buffer->cpu)) {
+		DPRINTK("Process(pid=%d) is not allowed to control this buffer list(cpu=%d).\n", current->pid, buffer->cpu);
+		spin_unlock(&lkst_buffer_lock);
+		return -EBUSY;
+	}		
+
+			/* Check whether this buffer is used currently. */
+	if (lkst.current_buffer_id[buffer->cpu] == id) {
+		DPRINTK("Specified buffer(ID=%d) is currently used!\n", id);
+		spin_unlock(&lkst_buffer_lock);
+		return -EBUSY;
+	}
+
+			/* Invalidate buffer pointer */
+	LKST_POINTER_INVALIDATE(lkst.buffer_table[id].bufferp);
+
+			/* Wait until all the event handlers exit. */
+	while (atomic_read(&(lkst.refcnt)));
+
+			/* Reconfirm this buffer is not used currently. */
+	if (lkst.current_buffer_id[buffer->cpu] == id) {
+		DPRINTK("Specified buffer(ID=%d) is currently used!\n", id);
+
+			/* Restore buffer pointer */
+		lkst.buffer_table[id].bufferp = buffer;
+		LKST_POINTER_CHECK_INIT(lkst.buffer_table[id].bufferp);
+
+		spin_unlock(&lkst_buffer_lock);
+		return -EBUSY;
+	}
+
+	if (buffer->prev != LKST_BUFFER_ID_VOID) {
+		if (!LKST_POINTER_VERIFY_STRICT
+		    (lkst.buffer_table[buffer->prev].bufferp,
+		     prev_buffer)) {
+			DPRINTK("Previous buffer(ID=%d) is collapsed!\n", buffer->prev);
+		} else {
+			/* change next ID of previous buffer */
+			prev_buffer->next = buffer->next;
+		}
+	}
+	else if (lkst.buffer_head[buffer->cpu] != id) { // for debug
+		DPRINTK("Buffer list. (buffer_head[%d] of event_buffer) is collapsed!\n", buffer->cpu);
+	}
+
+	if (buffer->next != LKST_BUFFER_ID_VOID) {
+		if (!LKST_POINTER_VERIFY_STRICT
+		    (lkst.buffer_table[buffer->next].bufferp,
+		     next_buffer)) {
+			DPRINTK("Next buffer(ID=%d) is collapsed!\n", buffer->next);
+		} else {
+			/* chane prev ID of next buffer */
+			next_buffer->prev = buffer->prev;
+		}
+	}
+	else if (lkst.buffer_tail[buffer->cpu] != id) { // for debug
+		DPRINTK("Buffer list. (buffer_tail[%d] of event_buffer) is collapsed!\n", buffer->cpu);
+	}
+
+	if (lkst.buffer_tail[buffer->cpu] == id) {
+		/* modify buffer_tail */
+		lkst.buffer_tail[buffer->cpu] = buffer->prev;
+	}
+
+	if (lkst.buffer_head[buffer->cpu] == id) {
+		/* modify buffer_head */
+		lkst.buffer_head[buffer->cpu] = buffer->next;
+	}
+
+	/* free buffer area */
+	vfree(buffer);
+
+	spin_unlock(&lkst_buffer_lock);
+
+	return (0);
+}
+
+
+static __inline__ int lkst_buffer_list_core(struct lkst_buffer_listparam *lp)
+{
+	int i, cnt, cnt_max;
+	size_t buff_size;
+	struct lkst_event_buffer *buffer;
+	struct lkst_event_record *prev_entry;
+
+	/* !NOTE!: please check (lp != NULL) before calling this.*/
+	if(lp->listent_size < sizeof(struct lkst_buffer_listent) ||
+	   lp->listent_size > LKST_BUFFER_LISTENT_SIZE(LKST_BUFFER_TBL_MAX)) {
+		DPRINTK("Invalid listent_size=%d\n", lp->listent_size);
+		return -EINVAL;
+	}
+
+	cnt = 0;
+	cnt_max = lp->listent_size / sizeof(struct lkst_buffer_listent);
+
+	for (i = 0; i < cnt_max; i++) {
+		lp->listent[i].id = LKST_BUFFER_ID_VOID;
+		lp->listent[i].size = 0;
+		lp->listent[i].readp = 0;
+		lp->listent[i].writep = 0;
+		lp->listent[i].wrap_flag = LKST_FLAG_NO;
+		lp->listent[i].prev = 0;
+		lp->listent[i].next = 0;
+		lp->listent[i].cpu = -1;
+	}
+
+	for (i = 0; i < LKST_BUFFER_TBL_MAX; i++) {
+		spin_lock(&lkst_buffer_lock);
+		if (!LKST_POINTER_VERIFY_STRICT(lkst.buffer_table[i].bufferp, buffer)) {
+			spin_unlock(&lkst_buffer_lock);
+			continue;
+		}
+
+		buff_size = buffer->size;
+
+		lp->listent[cnt].id = buffer->id;
+		lp->listent[cnt].size = buff_size;
+		lp->listent[cnt].readp = buffer->readp;
+		lp->listent[cnt].prev = buffer->prev;
+		lp->listent[cnt].next = buffer->next;
+		lp->listent[cnt].cpu = buffer->cpu;
+		lp->listent[cnt].current_flag = 
+			(lkst.current_buffer_id[buffer->cpu] == buffer->id)? LKST_FLAG_YES : LKST_FLAG_NO;
+		lp->listent[cnt].writep = 
+			atomic_read(&(buffer->writep)) & (buff_size - 1);
+
+		(char *) prev_entry =
+			(char *) (buffer->body) + buffer->last_readp;
+
+		if (buffer->last_recid != prev_entry->log_recid) 
+			lp->listent[cnt].wrap_flag = LKST_FLAG_YES;
+
+		spin_unlock(&lkst_buffer_lock);
+
+		cnt++;
+		if (cnt > cnt_max) return 0;
+	}
+
+	return 0;
+}
+
+
+static __inline__ int lkst_buffer_ring_core(struct lkst_buffer_ringparam *param)
+{
+	lkst_buffer_id head_id, tail_id;
+	struct lkst_event_buffer *head_buffer, *tail_buffer;
+
+	/* !NOTE!: please check (param != NULL) before calling this.*/
+	if (param->cpu >= smp_num_cpus || param->cpu < 0) {
+		DPRINTK("Invalid CPU number=%d\n", param->cpu);
+		return -EINVAL;
+	}
+
+	spin_lock(&lkst_buffer_lock);
+
+			/* Wait until all the event handlers exit. */
+	while (atomic_read(&(lkst.refcnt)));
+
+	head_id = lkst.buffer_head[param->cpu];
+	tail_id = lkst.buffer_tail[param->cpu];
+
+	if (!LKST_POINTER_VERIFY_STRICT(lkst.buffer_table[head_id].bufferp, head_buffer)) {
+		DPRINTK("Buffer head (ID=%d) of CPU=%d does not exist!\n", head_id, param->cpu);
+		spin_unlock(&lkst_buffer_lock);
+		return -EBUSY;
+	}
+
+	if (!LKST_POINTER_VERIFY_STRICT(lkst.buffer_table[tail_id].bufferp, tail_buffer)) {
+		DPRINTK("Buffer tail (ID=%d) of CPU=%d does not exist!\n", tail_id, param->cpu);
+		spin_unlock(&lkst_buffer_lock);
+		return -EBUSY;
+	}
+
+	if (param->ring) {
+		/* Change buffer link structure to buffer ring */
+		if (head_id == tail_id) {
+			DPRINTK("Multiple buffers are needed on the buffer link!\n", "");
+			spin_unlock(&lkst_buffer_lock);
+			return -EINVAL;
+		}
+
+		lkst.buffer_ring[param->cpu] = 1;
+
+		/* Connect head and tail of buffer link */
+		head_buffer->prev = tail_id;
+		tail_buffer->next = head_id;
+
+	} else {
+		/* Change buffer link structure to buffer list */
+
+		lkst.buffer_ring[param->cpu] = 0;
+
+		/* Disconnect head and tail of buffer link */
+		head_buffer->prev = LKST_BUFFER_ID_VOID;
+		tail_buffer->next = LKST_BUFFER_ID_VOID;
+	}
+
+	spin_unlock(&lkst_buffer_lock);
+
+	return (0);
+}
+
+
+int lkst_buffer_setrmod_core(struct lkst_buffer_srmodparam *sp,
+			     struct file *filp)
+{
+	struct lkst_event_buffer *head_buffer;
+	lkst_buffer_id head_id;
+	int cpu;
+
+	/* !NOTE!: please check (filp != NULL && sp != NULL) before calling this.*/
+	if ((lkst_buffer_id) (filp->private_data) != LKST_BUFFER_ID_VOID) {
+		DPRINTK("This process(pid=%d) is already set to read other buffer list.\n", current->pid);
+		return -EBUSY;
+	}
+
+	cpu = sp->cpu;
+	
+	if (cpu >= smp_num_cpus || cpu < 0) {
+		DPRINTK("Invalid CPU number=%d\n", cpu);
+		return -EINVAL;
+	}
+
+	if (lkst.buffer_owner[cpu] != (PID_MAX + 1)) {
+		DPRINTK("Specified buffer list is already set reading mode by pid=%d\n",
+			lkst.buffer_owner[cpu]);
+		return -EBUSY;
+	}
+
+	spin_lock(&lkst_buffer_lock);
+
+	head_id = lkst.buffer_head[cpu];
+
+	if (!LKST_POINTER_VERIFY_STRICT(lkst.buffer_table[head_id].bufferp, head_buffer)) {
+		DPRINTK("Buffer head (ID=%d) of CPU=%d does not exist!\n", head_id, cpu);
+		spin_unlock(&lkst_buffer_lock);
+		return -EBUSY;
+	}
+
+	if (!lkst.buffer_ring[cpu]) {
+		/* buffer is in list structure */
+		(lkst_buffer_id) (filp->private_data) = head_id;
+	} else {
+		/* buffer is in ring structure */
+		(lkst_buffer_id) (filp->private_data) =
+			lkst.current_buffer_id[cpu];
+	}
+
+	/* Set owner pid to the buffer list of specified CPU */ 
+	lkst.buffer_owner[cpu] = current->pid;
+
+	/* get buffer time stamp */
+	sp->tsc = lkst.tsc;
+	sp->xtime.tv_sec = lkst.xtime.tv_sec;
+	sp->xtime.tv_usec = lkst.xtime.tv_usec;
+	sp->cpu_freq = lkst.cpu_freq;
+	sp->buf_ver = lkst.buf_ver;
+	strncpy(sp->arch, lkst.arch, LKST_ARCH_NAME_LEN);
+	sp->endian_big = lkst.endian_big;
+
+	spin_unlock(&lkst_buffer_lock);
+
+	return (0);
+}
+
+
+void lkst_buffer_dump_current_txt(void)
+{
+	int i;
+	int cpu;
+	lkst_maskset_id id;
+	int err_f;
+	struct lkst_event_record *buff_body;
+	size_t buff_size;
+	unsigned int *pArgs;
+	lkst_buffer_id buffer_id;
+	struct lkst_event_buffer *buffer;
+	int	event_type;
+	char	*event_type_name;
+
+	/* stop tracing */
+	id = LKST_MASKSET_ID_RNOTHING;
+	err_f = lkst_maskset_xchg(&id);
+
+	if (!LKST_POINTER_VERIFY_STRICT
+	    (lkst.buffer_table[0].bufferp, buffer)) {
+		DPRINTK("Kernel State Tracer was not initialized\n", "");
+	} else {
+		for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+			buffer_id =lkst.current_buffer_id[cpu];
+			if (!((buffer_id <= LKST_BUFFER_ID_MAX) &&
+			      (LKST_POINTER_VERIFY_STRICT(lkst.buffer_table[buffer_id].bufferp, buffer)))) 
+				continue;
+
+			buff_size = buffer->size - 1;
+
+			for (i = 0; i <= (buff_size + 1 - sizeof(struct lkst_event_record)); i += sizeof(struct lkst_event_record)) {
+				(char *)buff_body = (char *)LKST_BUFFER_BODY_TOP(buffer) +
+					((i + buffer->writep.counter) & (unsigned int)buff_size);
+				event_type = buff_body->log_event_type;
+
+					/* Stop dump if buffer pointer 
+					   reaches unused entry. */
+				if (!LKST_ETYPE_VERIFY(event_type)) continue;
+
+				event_type_name = lkst_event_type_descriptions[event_type];
+
+				printk("0x%08x: %016llu [mc], \\\n"
+				       " type: %25s(0x%04x), pid: %010u, cpu: %03u \\\n",
+				       buff_body->log_recid,
+				       buff_body->log_time,
+				       event_type_name, event_type,
+				       buff_body->log_pid,
+				       cpu);
+
+				pArgs = (unsigned int *) &buff_body->log_arg1;
+				printk("  0x%08x 0x%08x 0x%08x 0x%08x \\\n"
+				       "  0x%08x 0x%08x 0x%08x 0x%08x \\\n\n",
+				       pArgs[0], pArgs[1], pArgs[2], pArgs[3], 
+				       pArgs[4], pArgs[5], pArgs[6], pArgs[7]);
+
+			}	/* i */
+		}		/* cpu */
+
+	}
+
+	/* restart tracing */
+	printk("id: %010u\n", id);
+	if (!err_f)
+		lkst_maskset_xchg(&id);
+
+	return ;
+}
+
+int lkst_evhandler_register(lkst_evhandler_id id, char *name,
+			    lkst_evhandler_func evhandler,
+			    lkst_evhandler_ctrl_func evhandler_ctrl)
+{
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (id > LKST_EVHANDLER_ID_MAX) {
+		DPRINTK("Invalid handler ID = %d\n", id);
+		return -EINVAL;
+	}
+	if (name != NULL) {
+		strncpy(lkst.evhandler_table[id].name, name,
+			(size_t) LKST_EVHANDLER_NAME_LEN);
+		lkst.evhandler_table[id].name[LKST_EVHANDLER_NAME_LEN - 1] = '\0';
+	} else {
+		lkst.evhandler_table[id].name[0] = '\0';		
+	}
+	lkst.evhandler_table[id].evhandler = evhandler;
+	if (evhandler != NULL)
+		LKST_POINTER_CHECK_INIT(lkst.evhandler_table[id].evhandler);
+	else
+		lkst.evhandler_table[id].evhandler_check = 0;
+
+	lkst.evhandler_table[id].evhandler_ctrl = evhandler_ctrl;
+	if (evhandler_ctrl != NULL)
+		LKST_POINTER_CHECK_INIT(lkst.evhandler_table[id].
+					evhandler_ctrl);
+	else
+		lkst.evhandler_table[id].evhandler_ctrl_check = 0;
+
+	lkst_hook_exit_update(id);
+
+	return 0;
+}
+
+#if DEBUG
+int lkst_ioc_diag(long arg)
+{
+	int cpu = smp_processor_id();
+
+	if (copy_from_user(&(lkst_diag_argdata[cpu]),
+		       (struct lkst_diag_arg *) arg,
+			   sizeof(lkst_diag_argdata[cpu]))) {
+  		DPRINTK("Reading fail at user memory address %p\n", arg);
+		return -EINVAL;
+	}
+
+
+	return ((*lkst_diag_argdata[cpu].func) ((char *) &(lkst_diag_argdata[cpu].arg)));
+}
+#endif /* DEBUG */
+
+
+/* kernel trc_status wrap function */
+int lkst_trc_status(struct lkst_status_param *param)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (param == NULL) { 
+		printk(KERN_ERR "Warning : argument param is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_trc_status_core(param);
+}
+
+/* kernel trc_start wrap function */
+int lkst_trc_start()
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_trc_start_core();
+}
+
+/* kernel trc_stop wrap function */
+int lkst_trc_stop()
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_trc_stop_core();
+}
+
+/* kernel maskset_read wrap function */
+int lkst_maskset_read(struct lkst_maskset_param *param)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (param == NULL) { 
+		printk(KERN_ERR "Warning : argument param is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_maskset_read_core(param);
+}
+
+/* kernel maskset_write wrap function */
+int lkst_maskset_write(struct lkst_maskset_param *param)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (param == NULL) { 
+		printk(KERN_ERR "Warning : argument param is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_maskset_write_core(param);
+}
+
+/* kernel maskset_xchg wrap function */
+int lkst_maskset_xchg(lkst_maskset_id * id)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (id == NULL) { 
+		printk(KERN_ERR "Warning : argument id is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_maskset_xchg_core(id);
+}
+
+/* kernel maskset_set wrap function */
+int lkst_maskset_set(lkst_maskset_id id)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_maskset_xchg_core(&id);
+}
+
+/* kernel maskset_list wrap function */
+int lkst_maskset_list(struct lkst_maskset_listparam *lp)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (lp == NULL) { 
+		printk(KERN_ERR "Warning : argument lp is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_maskset_list_core(lp);
+}
+
+/* kernel maskset_delete wrap function */
+int lkst_maskset_delete(lkst_maskset_id id)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_maskset_delete_core(id);
+}
+
+/* kernel evhandler_list wrap function */
+int lkst_evhandler_list(struct lkst_evhandler_listparam *lp)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (lp == NULL) { 
+		printk(KERN_ERR "Warning : argument lp is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_evhandler_list_core(lp);
+}
+
+/* kernel evhandler_ctrl wrap function */
+int lkst_evhandler_ctrl(struct lkst_evhandler_ctrl_param
+			*evhandler_ctrl_param)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (evhandler_ctrl_param == NULL) { 
+		printk(KERN_ERR "Warning : argument evhandler_ctrl_param is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_evhandler_ctrl_core(evhandler_ctrl_param);
+}
+
+/* kernel buffer_read wrap function */
+int lkst_buffer_read(struct lkst_log_buffer *lbuffer)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (lbuffer == NULL) { 
+		printk(KERN_ERR "Warning : argument lbuffer is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_buffer_read_core(lbuffer, 0);
+}
+
+#if DEBUG
+/* kernel buffer_seek wrap function */
+int lkst_buffer_seek(struct lkst_buffer_seekparam *bs)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (bs == NULL) { 
+		printk(KERN_ERR "Warning : argument bs is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_buffer_seek_core(bs);
+}
+#endif /* DEBUG */
+
+/* kernel buffer_create wrap function */
+int lkst_buffer_create(struct lkst_buffer_param *param)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (param == NULL) { 
+		printk(KERN_ERR "Warning : argument param is NULL!\n");
+		return -EINVAL;
+	}
+	
+	return lkst_buffer_create_core(param);
+}
+
+/* kernel buffer_shift wrap function */
+int lkst_buffer_shift(int cpu)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_buffer_shift_core(cpu);
+}
+
+/* kernel buffer_delete wrap function */
+int lkst_buffer_delete(lkst_buffer_id id)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_buffer_delete_core(id);
+}
+
+/* kernel buffer_list wrap function */
+int lkst_buffer_list(struct lkst_buffer_listparam *lp)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (lp == NULL) { 
+		printk(KERN_ERR "Warning : argument lp is NULL!\n");
+		return -EINVAL;
+	}
+
+	return lkst_buffer_list_core(lp);
+}
+
+/* kernel buffer_ring wrap function */
+int lkst_buffer_ring(struct lkst_buffer_ringparam *rp)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (rp == NULL) { 
+		printk(KERN_ERR "Warning : argument rp is NULL!\n");
+		return -EINVAL;
+	}
+	
+	return lkst_buffer_ring_core(rp);
+}
+
+
+/*********************************************************************
+ * ioctl functions (static *CLOSED* functions)
+ ********************************************************************/
+
+/* ioctl trc_status wrap function */
+static int lkst_trc_status_ioctl(struct lkst_status_param *param_user)
+{
+	int retval = 0;
+	struct lkst_status_param param;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	retval = lkst_trc_status_core(&param);
+
+	if (copy_to_user(param_user, &param, sizeof(struct lkst_status_param))) {
+		DPRINTK("Writing fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	return retval;
+}
+
+/* ioctl trc_start wrap function */
+static int lkst_trc_start_ioctl(void)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_trc_start_core();
+}
+
+/* ioctl trc_stop wrap function */
+static int lkst_trc_stop_ioctl(void)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_trc_stop_core();
+}
+
+/* ioctl maskset_read wrap function */
+static int lkst_maskset_read_ioctl(struct lkst_maskset_param *param_user)
+{
+	int retval = 0;
+	struct lkst_maskset_param param;
+	struct lkst_maskset_body *maskset;
+	struct lkst_maskset_body *user_maskset;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_maskset_param))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	if (param.maskset_size <= 0 || verify_area(VERIFY_WRITE, param.maskset, param.maskset_size)) {
+		DPRINTK("Invalid argument(maskset/maskset_size)\n");
+		return -EINVAL;
+	}
+
+	user_maskset = param.maskset;
+	maskset = vmalloc(param.maskset_size);
+	if (maskset == NULL) {
+		DPRINTK("Cannot allocate kernel memory : size=%d\n", param.maskset_size);
+		return -ENOMEM;
+	}
+
+	param.maskset = maskset;
+	retval = lkst_maskset_read_core(&param);
+
+	if (copy_to_user(user_maskset, param.maskset, param.maskset_size)) {
+		DPRINTK("Writing fail at user memory address %p\n", user_maskset);
+		return -EINVAL;
+	}
+
+	param.maskset = user_maskset;
+
+	if (copy_to_user(param_user, &param, sizeof(struct lkst_maskset_param))) {
+		DPRINTK("Writing fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	vfree(maskset);
+
+	return retval;
+}
+
+/* ioctl maskset_write wrap function */
+static int lkst_maskset_write_ioctl(struct lkst_maskset_param *param_user)
+{
+	int retval = 0;
+	struct lkst_maskset_param param;
+	struct lkst_maskset_body *maskset, *save_user_maskset;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_maskset_param))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	if (param.maskset_size <= 0 || verify_area(VERIFY_READ, param.maskset, param.maskset_size)) {
+		DPRINTK("Ibvalid argument(maskset/maskset_size)\n", "");
+		return -EINVAL;
+	}
+
+	maskset = vmalloc(param.maskset_size);
+	if (maskset == NULL) {
+		DPRINTK("Cannot allocate kernel memory : size=%d\n", param.maskset_size);
+		return -ENOMEM;
+	}
+
+	if (copy_from_user(maskset, param.maskset, param.maskset_size)) {
+		DPRINTK("Reading fail at user memory address %p\n", param.maskset);
+		return -EINVAL;
+	}
+
+	save_user_maskset = param.maskset;
+	param.maskset = maskset;
+
+	retval = lkst_maskset_write_core(&param);
+
+	param.maskset = save_user_maskset;
+
+	if (copy_to_user(param_user, &param, sizeof(struct lkst_maskset_param))) {
+		DPRINTK("Writing fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	vfree(maskset);
+
+	return retval;
+}
+
+/* ioctl maskset_set wrap function */
+static int lkst_maskset_set_ioctl(lkst_maskset_id id)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_maskset_xchg_core(&id);
+}
+
+/* ioctl maskset_list wrap function */
+static int lkst_maskset_list_ioctl(struct lkst_maskset_listparam *param_user)
+{
+	int retval = 0;
+	struct lkst_maskset_listparam param;
+	struct lkst_maskset_listent *listent;
+	struct lkst_maskset_listent *user_listent;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_maskset_listparam))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+
+	if (param.listent_size <= 0 || verify_area(VERIFY_WRITE, param.listent, param.listent_size)) {
+		DPRINTK("Invalid argument(listent/listent_size)\n", "");
+		return -EINVAL;
+	}
+	
+	user_listent = param.listent;
+	listent = vmalloc(param.listent_size);
+	if (listent == NULL) {
+		DPRINTK("Cannot allocate kernel memory : size=%d\n", param.listent_size);
+		return -ENOMEM;
+	}
+
+	param.listent = listent;
+
+	retval = lkst_maskset_list_core(&param);
+
+	if (copy_to_user(user_listent, param.listent, param.listent_size)) {
+		DPRINTK("Writing fail at user memory address %p\n", user_listent);
+		return -EINVAL;
+	}
+
+	param.listent = user_listent;
+
+	if (copy_to_user(param_user, &param,
+			 sizeof(struct lkst_maskset_listparam))) {
+		DPRINTK("Writing fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	vfree(listent);
+
+	return retval;
+}
+
+/* ioctl maskset_delete wrap function */
+static int lkst_maskset_delete_ioctl(lkst_maskset_id id)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_maskset_delete_core(id);
+}
+
+/* ioctl evhandler_list wrap function */
+static int lkst_evhandler_list_ioctl(struct lkst_evhandler_listparam *param_user)
+{
+	int retval = 0;
+	struct lkst_evhandler_listparam param;
+	struct lkst_evhandler_listent *listent;
+	struct lkst_evhandler_listent *user_listent;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_evhandler_listparam))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+
+	if (param.listent_size <= 0 || verify_area(VERIFY_WRITE, param.listent, param.listent_size)) {
+		DPRINTK("Invalid argument(listent/listent_size)\n", "");
+		return -EINVAL;
+	}
+	
+	user_listent = param.listent;
+	listent = vmalloc(param.listent_size);
+	if (listent == NULL) {
+		DPRINTK("Cannot allocate kernel memory : size=%d\n", param.listent_size);
+		return -ENOMEM;
+	}
+
+	param.listent = listent;
+
+	retval = lkst_evhandler_list_core(&param);
+
+	if (copy_to_user(user_listent, param.listent, param.listent_size)) {
+		DPRINTK("Writing fail at user memory address %p\n", user_listent);
+		return -EINVAL;
+	}
+
+	vfree(listent);
+
+	return retval;
+}
+
+/* ioctl evhandler_ctrl wrap function */
+static int lkst_evhandler_ctrl_ioctl(struct lkst_evhandler_ctrl_param *param_user)
+{
+	int retval = 0;
+	struct lkst_evhandler_ctrl_param param;
+	char *buf = NULL;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_evhandler_ctrl_param))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+
+	if (param.bufsize < 0 || verify_area(VERIFY_READ, param.buf, param.bufsize)) {
+		DPRINTK("Invalid argument(buf/bufsize)\n", "");
+		return -EINVAL;
+	}
+
+	if (param.bufsize != 0) {
+		buf = vmalloc(param.bufsize);
+		if (buf == NULL) {
+			DPRINTK("Cannot allocate kernel memory : size=%d\n", param.bufsize);
+			return -ENOMEM;
+		}
+
+		if (copy_from_user(buf, param.buf, param.bufsize)) {
+			DPRINTK("Reading fail at user memory address %p\n", param.buf);
+			return -EINVAL;
+		}
+	}
+
+	param.buf = buf;
+
+	retval = lkst_evhandler_ctrl_core(&param);
+
+	if (copy_to_user(param_user, &param, sizeof(struct lkst_evhandler_ctrl_param))) {
+  		DPRINTK("Writing fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	if (buf != NULL)
+		vfree(buf);
+
+	return retval;
+}
+
+/* ioctl buffer_read wrap function */
+static int lkst_buffer_read_ioctl(struct lkst_log_buffer *lbuffer_user)
+{
+	int retval = 0;
+	struct lkst_log_buffer lbuffer;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&lbuffer, lbuffer_user, sizeof(struct lkst_log_buffer))) {
+	  	DPRINTK("Reading fail at user memory address %p\n", lbuffer_user);
+		return -EINVAL;
+	}
+
+
+	if (lbuffer.read_size <= 0 || verify_area(VERIFY_WRITE, lbuffer.buffer, lbuffer.read_size)) {
+		DPRINTK("Invalid argument(buffer/read_size)\n", "");
+		return -EINVAL;
+	}
+
+	retval = lkst_buffer_read_core(&lbuffer, 1);
+
+	if (copy_to_user(lbuffer_user, &lbuffer, sizeof(struct lkst_log_buffer))) {
+		DPRINTK("Writing fail at user memory address %p\n", lbuffer_user);
+		return -EINVAL;
+	}
+
+	return retval;
+}
+
+#if DEBUG
+/* ioctl buffer_seek wrap function */
+static int lkst_buffer_seek_ioctl(struct lkst_buffer_seekparam *bs_user)
+{
+	int retval = 0;
+	struct lkst_buffer_seekparam bs;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&bs, bs_user, sizeof(struct lkst_buffer_seekparam))) {
+		DPRINTK("Reading fail at user memory address %p\n", bs_user);
+		return -EINVAL;
+	}
+
+	retval = lkst_buffer_seek_core(&bs);
+
+	if (copy_to_user(bs_user, &bs, sizeof(struct lkst_buffer_seekparam))) {
+		DPRINTK("Writing fail at user memory address %p\n", bs_user);
+		return -EINVAL;
+	}
+
+	return retval;
+}
+#endif /* DEBUG */
+
+/* ioctl buffer_create wrap function */
+static int lkst_buffer_create_ioctl(struct lkst_buffer_param *param_user)
+{
+	int retval = 0;
+	struct lkst_buffer_param param;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_buffer_param))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	retval = lkst_buffer_create_core(&param);
+
+	if (copy_to_user(param_user, &param, sizeof(struct lkst_buffer_param))) {
+		DPRINTK("Writing fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	return retval;
+}
+
+
+/* ioctl buffer_shift wrap function */
+static int lkst_buffer_shift_ioctl(int arg)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_buffer_shift_core(arg);
+}
+
+/* ioctl buffer_delete wrap function */
+static int lkst_buffer_delete_ioctl(lkst_buffer_id arg)
+{
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return lkst_buffer_delete_core(arg);
+}
+
+/* ioctl buffer_list wrap function */
+static int lkst_buffer_list_ioctl(struct lkst_buffer_listparam *param_user)
+{
+	int retval = 0;
+	struct lkst_buffer_listparam param;
+	struct lkst_buffer_listent *listent;
+	struct lkst_buffer_listent *user_listent;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_buffer_listparam))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+
+	if (param.listent_size <= 0 || verify_area(VERIFY_WRITE, param.listent, param.listent_size)) {
+		DPRINTK("Invalid argument(listent/listent_size)\n", "");
+		return -EINVAL;
+	}
+	
+	user_listent = param.listent;
+	listent = vmalloc(param.listent_size);
+	if (listent == NULL) {
+		DPRINTK("Cannot allocate kernel memory : size=%d\n", param.listent_size);
+		return -ENOMEM;
+	}
+
+	param.listent = listent;
+
+	retval = lkst_buffer_list_core(&param);
+
+	if (copy_to_user(user_listent, param.listent, param.listent_size)) {
+		DPRINTK("Writing fail at user memory address %p\n", user_listent);
+		return -EINVAL;
+	}
+	vfree(listent);
+
+	return retval;
+}
+
+/* ioctl buffer_ring wrap function */
+static int lkst_buffer_ring_ioctl(struct lkst_buffer_ringparam *param_user)
+{
+	struct lkst_buffer_ringparam param;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_buffer_ringparam))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	return lkst_buffer_ring_core(&param);
+}
+
+/* ioctl buffer_setrmod wrap function */
+static int lkst_buffer_setrmod_ioctl(struct lkst_buffer_srmodparam *param_user,
+			  struct file *filp)
+{
+	int retval = 0;
+	struct lkst_buffer_srmodparam param;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&param, param_user, sizeof(struct lkst_buffer_srmodparam))) {
+		DPRINTK("Reading fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	retval = lkst_buffer_setrmod_core(&param, filp);
+
+	if (copy_to_user(param_user, &param, sizeof(struct lkst_buffer_srmodparam))) {
+		DPRINTK("Writing fail at user memory address %p\n", param_user);
+		return -EINVAL;
+	}
+
+	return retval;
+}
+
+/* ioctl entry_log wrap function */
+static int lkst_entry_log_ioctl(struct lkst_entry_args *arg_user)
+{
+	struct lkst_entry_args arg;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&arg, arg_user, sizeof(struct lkst_entry_args))) {
+		DPRINTK("Reading fail at user memory address %p\n", arg_user);
+		return -EINVAL;
+	}
+
+	(void) lkst_entry_log(NULL, arg.event_type,
+			      arg.arg1, arg.arg2, arg.arg3, arg.arg4);
+
+	return (0);
+}
+
+
+/* LKST device open function */
+int lkst_open(struct inode *inode, struct file *filp)
+{
+
+#ifdef MODULE
+	/* Increment module reference count */
+	MOD_INC_USE_COUNT;
+#endif /* MODULE */
+
+	/* Initialize reading ID of buffer which used by "lkstlogd" */
+	(lkst_buffer_id) filp->private_data = LKST_BUFFER_ID_VOID;
+
+	return (0);
+}
+
+
+/* LKST device close function */
+int lkst_close(struct inode *inode, struct file *filp)
+{
+
+	int i;
+#ifdef MODULE
+	/* Decrement module reference count */
+	MOD_DEC_USE_COUNT;
+#endif /* MODULE */
+
+	/* Clear owner pid of buffer list */
+	for (i = 0; i < LKST_CPU_MAX; i++) {
+		if (lkst.buffer_owner[i] == current->pid) {
+			lkst.buffer_owner[i] = PID_MAX + 1;
+			break;
+		}
+	}
+
+	return (0);
+}
+
+
+/* LKST device read function */
+ssize_t lkst_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+	ssize_t retval, result_size = 0;
+	lkst_buffer_id id;
+	struct lkst_log_buffer lbuffer;
+	struct lkst_event_buffer *buffer;
+	int cpu;
+	int rcnt, wcnt, rwdiff;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if ((lkst_buffer_id) (filp->private_data) == LKST_BUFFER_ID_VOID) {
+		DPRINTK("This process(pid=%d) is not initialized in LKST, Please use command ioctl(%d,..)\n", current->pid, LKST_IOC_BUFFER_SETRMOD);
+		return -EBUSY;
+	}
+
+	if (count <= 0 || verify_area(VERIFY_WRITE, buf, count)) {
+		DPRINTK("Invalid argument(buf/count)\n", "");
+		return -EINVAL;
+	}
+
+	id = (lkst_buffer_id) (filp->private_data);
+
+	do {
+		if (!LKST_POINTER_VERIFY(lkst.buffer_table[id].bufferp, buffer)) {
+			DPRINTK("Buffer(ID=%d) does not exist!\n", id);
+			return -EBUSY;
+		}
+
+		cpu = buffer->cpu;
+
+		rcnt = atomic_read(&(buffer->rcnt));
+
+		/* Increment buffer read count */
+		if ((rcnt % 2) == 0) {
+			atomic_inc(&(buffer->rcnt));
+			rcnt++;
+		}
+
+		wcnt = atomic_read(&(buffer->wcnt));
+
+		rwdiff = wcnt - rcnt;
+
+		if (rwdiff >= 2 || rwdiff < 0) {
+			if (rwdiff <= -2) /* wcnt/rcnt overflow */
+				atomic_set(&(buffer->rcnt),
+					   wcnt - 1 + (rwdiff % 2));
+			else if (rwdiff >= 2) /* buffer is wrapped */
+				atomic_set(&(buffer->rcnt),
+					   wcnt - 1 - (rwdiff % 2));
+			LKST_BUFFER_READP_RESET(buffer);
+			id = buffer->next;
+			/* Set last read buffer ID */
+			(lkst_buffer_id) (filp->private_data) = id;
+			return -EAGAIN;
+		} else if (rwdiff == 0) {
+			/* process sleep on */
+			interruptible_sleep_on(&lkst.buffer_wq[cpu]);
+		}
+
+		lbuffer.read_size = count;
+		(char *) lbuffer.buffer = buf + result_size;
+		lbuffer.id = id;
+		lbuffer.result_read_size = 0;
+
+		retval = lkst_buffer_read_core(&lbuffer, 2);
+
+		if (retval)
+			return retval;
+
+		if (signal_pending(current)) /* singal pending */
+			return lbuffer.result_read_size + result_size;
+
+		/* Read whole buffer */
+		if (lbuffer.id != id) {
+			LKST_BUFFER_READP_RESET(buffer);
+			id = lbuffer.id;
+			atomic_inc(&(buffer->rcnt));
+			/* Set last read buffer ID */
+			(lkst_buffer_id) (filp->private_data) = id;
+		}
+
+		count -= lbuffer.result_read_size;
+
+		result_size += lbuffer.result_read_size;
+
+	} while (count >= LKST_BUFFER_SIZE_LOCAL2EXT(LKST_BUFFER_HEADSPACE));
+
+	return result_size;
+}
+
+
+/* LKST device ioctl function */
+int lkst_ioctl(struct inode *inode, struct file *filp,
+	       unsigned int request, unsigned long arg)
+{
+	int retval = 0;		/* return value */
+
+	switch (request) {
+	case LKST_IOC_TRC_STATUS:
+		retval = 
+		    lkst_trc_status_ioctl((struct lkst_status_param *) arg);
+		break;
+	case LKST_IOC_TRC_START:
+		retval = lkst_trc_start_ioctl();
+		break;
+	case LKST_IOC_TRC_STOP:
+		retval = lkst_trc_stop_ioctl();
+		break;
+	case LKST_IOC_MASKSET_READ:
+		retval =
+		    lkst_maskset_read_ioctl((struct lkst_maskset_param *) arg);
+		break;
+	case LKST_IOC_MASKSET_WRITE:
+		retval =
+		   lkst_maskset_write_ioctl((struct lkst_maskset_param *) arg);
+		break;
+	case LKST_IOC_MASKSET_SET:
+		retval = lkst_maskset_set_ioctl((lkst_maskset_id) arg);
+		break;
+	case LKST_IOC_MASKSET_LIST:
+		retval =
+		    lkst_maskset_list_ioctl((struct lkst_maskset_listparam *) arg);
+		break;
+	case LKST_IOC_MASKSET_DELETE:
+		retval = lkst_maskset_delete_ioctl((lkst_maskset_id) arg);
+		break;
+	case LKST_IOC_EVHANDLER_LIST:
+		retval =
+		    lkst_evhandler_list_ioctl((struct lkst_evhandler_listparam *) arg);
+		break;
+	case LKST_IOC_EVHANDLER_CTRL:
+		retval =
+		    lkst_evhandler_ctrl_ioctl((struct lkst_evhandler_ctrl_param *) arg);
+		break;
+
+	case LKST_IOC_BUFFER_READ:
+		retval = 
+		    lkst_buffer_read_ioctl((struct lkst_log_buffer *) arg);
+		break;
+#if DEBUG
+	case LKST_IOC_BUFFER_SEEK:
+		retval = 
+		    lkst_buffer_seek_ioctl((struct lkst_buffer_seekparam *) arg);
+		break;
+#endif /* DEBUG */
+	case LKST_IOC_BUFFER_CREATE:
+		retval =
+		    lkst_buffer_create_ioctl((struct lkst_buffer_param *) arg);
+		break;
+	case LKST_IOC_BUFFER_SHIFT:
+		retval = lkst_buffer_shift_ioctl((int) arg);
+		break;
+	case LKST_IOC_BUFFER_DELETE:
+		retval = lkst_buffer_delete_ioctl((lkst_buffer_id) arg);
+		break;
+
+	case LKST_IOC_BUFFER_LIST:
+		retval = lkst_buffer_list_ioctl((struct lkst_buffer_listparam *) arg);
+		break;
+
+	case LKST_IOC_BUFFER_RING:
+		retval = lkst_buffer_ring_ioctl((struct lkst_buffer_ringparam *) arg);
+		break;
+
+	case LKST_IOC_BUFFER_SETRMOD:
+		retval = lkst_buffer_setrmod_ioctl((struct lkst_buffer_srmodparam *) arg, filp);
+		break;
+
+	case LKST_IOC_ENTRY_LOG:
+		retval =
+		    lkst_entry_log_ioctl((struct lkst_entry_args *) arg);
+		break;
+	default:
+		DPRINTK("Invalid command no.%d\n", request);
+		return -EINVAL;
+#if DEBUG
+	case LKST_IOC_DIAG:
+		retval = lkst_ioc_diag(arg);
+		break;
+#endif /* DEBUG */
+	}
+
+	return retval;
+}
+
+/*********************************************************************
+ * Initialize/cleanup functions
+ *********************************************************************/
+/*
+ * function lkst_trc_init_stage0
+ * Initialize the first part of Kernel State Tracer.
+ * This function initializes data not concerned with SMP.
+ * 
+ *  Arguments
+ *    NONE
+ *  returns
+ *    NONE
+ * 
+ */
+void lkst_trc_init_stage0()
+{
+	int i;
+
+	/* The following values are initialized when kernel was loaded,
+	 *   lkst.cpu_recid[...] = 1;
+	 *   maskset_rnothing[], maskset_rall[], maskset_rdefault[]
+	 */
+
+	printk("LKST: Starting initialization stage0\n");
+
+#ifdef CONFIG_MAGIC_SYSRQ
+	register_sysrq_key('v', &sysrq_lkst_dump_buffer_op);
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+	/* Initialize LKST header time stamp */
+	lkst_time_set(0);
+
+	/* Initialize stage0 buffer */
+	lkst_stage0_event_buffer.cmos_time_flag = lkst.cmos_time_flag;
+	lkst_stage0_event_buffer.xtime.tv_sec = lkst.xtime.tv_sec;
+	lkst_stage0_event_buffer.xtime.tv_usec = lkst.xtime.tv_usec;
+
+	/* set buffer_table */
+	lkst.buffer_table[0].bufferp = &lkst_stage0_event_buffer;
+	LKST_POINTER_CHECK_INIT(lkst.buffer_table[0].bufferp);
+
+	/* set current buffer */
+	lkst.current_buffer_id[0] = 0;
+
+	/* initialize current_buffer */
+	for (i = 1; i < LKST_CPU_MAX; i++) {
+		lkst.current_buffer_id[i] = LKST_BUFFER_ID_VOID;
+	}
+
+	/* initialize buffer_head/tail */
+	for (i = 0; i < LKST_CPU_MAX; i++) {
+		lkst.buffer_head[i] = LKST_BUFFER_ID_VOID;
+		lkst.buffer_tail[i] = LKST_BUFFER_ID_VOID;
+		lkst.buffer_ring[i] = 0;
+		lkst.buffer_owner[i] = PID_MAX + 1;
+		lkst.buffer_wq[i] = (wait_queue_head_t) __WAIT_QUEUE_HEAD_INITIALIZER(lkst.buffer_wq[i]);
+	}
+
+#if DEBUG
+	if (LKST_SIZEOF_LKST_EVENT_RECORD == sizeof(struct lkst_event_record)) {
+		/* Verification of LKST_SIZEOF_LKST_EVENT_RECORD is failed. */
+		printk(KERN_ERR "LKST error(init): sizeof(struct lkst_event_record) is not equal to LKST_SIZEOF_LKST_EVENT_RECORD.\n");
+		return;
+	}
+#endif /* DEBUG */
+
+	/* Clear entries for other Event Handlers */
+	for (i = 0; i < LKST_EVHANDLER_TBL_MAX; i++) {
+		lkst_evhandler_register(i, NULL, NULL, NULL);
+	}
+
+	/* Initialize Default Event Handler */
+	lkst_evhandler_register(LKST_EVHANDLER_ID_DEFAULT,
+				LKST_EVHANDLER_NAME_DEFAULT,
+				lkst_evhandler_default,
+				lkst_evhandler_default_ctrl);
+
+	/* Initialize Buffer Shift Event Handler */
+	lkst_evhandler_register(LKST_EVHANDLER_ID_BUFFER_SHIFT,
+				LKST_EVHANDLER_NAME_BUFFER_SHIFT,
+				lkst_evhandler_buffer_shift,
+				NULL);
+
+	/* Initialize Masetset Exchange Event Handler */
+	lkst_evhandler_register(LKST_EVHANDLER_ID_MASKSET_XCHG,
+				LKST_EVHANDLER_NAME_MASKSET_XCHG,
+				lkst_evhandler_maskset_xchg,
+				NULL);
+
+#if DEBUG
+	/* Initialize Exception Event Handler */
+	lkst_evhandler_register(LKST_EVHANDLER_ID_EXCEPTION,
+				LKST_EVHANDLER_NAME_EXCEPTION,
+				lkst_evhandler_exception,
+				NULL);
+#endif /* DEBUG */
+
+	/* Initialize Shifting buffer And Awaking Daemon Event Handler */
+	lkst_evhandler_register(LKST_EVHANDLER_ID_BUFFER_SHIFT_DW,
+				LKST_EVHANDLER_NAME_BUFFER_SHIFT_DW,
+				lkst_evhandler_buffer_shift_dw,
+				NULL);
+
+
+	/* Setup Special Masksets */
+	LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table,
+				     LKST_MASKSET_ID_RALL,
+				     LKST_MASKSET_NAME_RALL, maskset_rall);
+
+	LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table,
+				     LKST_MASKSET_ID_RNOTHING,
+				     LKST_MASKSET_NAME_RNOTHING,
+				     maskset_rnothing);
+
+	LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table,
+				     LKST_MASKSET_ID_RDEFAULT,
+				     LKST_MASKSET_NAME_RDEFAULT,
+				     maskset_rdefault);
+
+	/* Clear entries for other masksets */
+	for (i = 3; i < LKST_MASKSET_TBL_MAX; i++) {
+		lkst.maskset_table[i].masksetp = NULL;
+		lkst.maskset_table[i].masksetp_check = 0;
+	}
+
+	/* Setup current maskset pointer */
+	LKST_MASKSET_SET_CURRENT(LKST_MASKSET_ID_RDEFAULT);
+
+	/* GKHI hook Initialization */
+#ifndef MODULE
+	if(hook_init_in_start()){
+		printk("LKST: hook_init error\n");
+	}
+#endif /* MODULE */
+	lkst_trc_hook_init();
+	lkst_hook_maskset_xchg(lkst.current_maskset_id, LKST_MASKSET_ID_RNOTHING);
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_INIT, LKST_ARG32(0x0001, 0), 0, 0, 0);
+
+	printk("LKST: Initialization stage0 finished\n");
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_INIT, LKST_ARG32(0x00ff, 0), 0, 0, 0);
+}
+
+
+/*
+ * function lkst_trc_init_stage1
+ * Initialize the second part of Kernel State Tracer.
+ * This function initializes buffers, pointers and
+ * data concernd with SMP. Therefore, this should be
+ * called after all of the CPUs are initialized.
+ * 
+ *  Arguments
+ *    NONE
+ *  returns
+ *    NONE
+ * 
+ */
+void lkst_trc_init_stage1()
+{
+	int i;
+	struct lkst_buffer_param param;
+	struct lkst_event_buffer *buffer;
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_INIT, LKST_ARG32(0x0101, 0), 0, 0, 0);
+
+	printk("LKST: Starting initialization stage1\n");
+
+	/* Set architecture name */
+	strncpy(lkst.arch, system_utsname.machine, 65); 
+
+	/* Set cpu frequency */
+	lkst.cpu_freq = cpu_khz;
+
+#ifdef	CONFIG_DEBUG_KERNEL_STATE_TRACE_IN_START
+	/* Re-initialize time stamp */
+	lkst_time_set(0);
+	lkst_stage0_event_buffer.cmos_time_flag = lkst.cmos_time_flag;
+	lkst_stage0_event_buffer.xtime.tv_sec = lkst.xtime.tv_sec;
+	lkst_stage0_event_buffer.xtime.tv_usec = lkst.xtime.tv_usec;
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE_IN_START */
+
+	/* initialize buffer_table */
+	for (i = 1; i < LKST_BUFFER_TBL_MAX; i++) {
+		lkst.buffer_table[i].bufferp = NULL;
+		lkst.buffer_table[i].bufferp_check = 0;
+	}
+
+	/* allocate event buffer for all CPUs */
+	for (i = 0; i < smp_num_cpus; i++) {
+
+		printk("LKST: event buffer allocation CPU=%d\n", i);
+
+		param.id = i + 1;
+		param.cpu = i;
+		param.size = lkst_init_buffer_size;
+
+		/* create buffer for all CPUs */
+		if (lkst_buffer_create(&param)) {
+			printk(KERN_ERR "LKST warning(init): Cannot allocate buffer area!\n");
+			/* on error, free all buffers except CPU0's. */
+			for (i--; i >= 1; i--) {
+				vfree((void *)lkst.buffer_table[i + 1].bufferp);
+				lkst.buffer_table[i + 1].bufferp = NULL;
+				lkst.buffer_table[i + 1].bufferp_check = 0;
+			}
+			break;
+		}
+
+		if (!LKST_POINTER_VERIFY(lkst.buffer_table[i + 1].bufferp,
+					 buffer)) {
+			printk(KERN_ERR "LKST warning(init): allocated buffer area is collapsed! Please initialize again\n");
+			break;
+		}
+
+		/* set buffer_head */
+		lkst.buffer_head[i] = (i + 1);
+
+		/* increment buffer write count */
+		atomic_inc(&(buffer->wcnt));
+
+		/* set current buffer */
+		lkst.current_buffer_id[i] = (i + 1);
+	}
+
+	// TODO: device special file must be created automatically.
+	/* register LKST device file_operations */
+#ifdef CONFIG_DEVFS_FS
+	if (devfs_register_chrdev(LKST_DEV_MAJOR, LKST_DEV_NAME, &lkst_fops))
+		printk(KERN_ERR "LKST warning(init):cannot register LKST *conventional* device!\n");
+#else
+	if (register_chrdev(LKST_DEV_MAJOR, LKST_DEV_NAME, &lkst_fops))
+		printk(KERN_ERR "LKST error(init):cannot register LKST device!\n");
+#endif
+
+#ifdef CONFIG_DEVFS_FS
+        lkst_devfs_handle = devfs_register (NULL, LKST_DEV_NAME, DEVFS_FL_DEFAULT, LKST_DEV_MAJOR,
+				   LKST_DEV_MINOR, 0020644, &lkst_fops, NULL);
+	if ( lkst_devfs_handle == NULL )
+		printk(KERN_ERR "LKST error(init):cannot register LKST devfs device!\n");
+#endif
+
+	/* LKST initialize flag on */
+	lkst_init_flag = LKST_FLAG_YES;
+
+	printk("LKST: initialization stage1 finished\n");
+
+	/* LKST internal event */
+	lkst_entry_log(NULL, LKST_ETYPE_LKST_INIT, LKST_ARG32(0x10ff, 0), 0, 0, 0);
+}
+
+
+/*
+ * function lkst_trc_init_main
+ * Initialize basic part of Kernel State Tracer.
+ * This function is called from /init/main.c. and lkst_init_module
+ */
+void lkst_trc_init_main()
+{
+#ifndef	CONFIG_DEBUG_KERNEL_STATE_TRACE_IN_START
+	lkst_trc_init_stage0();
+#endif /* !CONFIG_DEBUG_KERNEL_STATE_TRACE_IN_START */
+	lkst_trc_init_stage1();
+}
+
+#ifdef MODULE
+static int __init lkst_init_module(void)
+{
+	size_t size;
+
+	printk("LKST: start LKST module.\n");
+
+	/* buffer size check */
+	printk("LKST: initial event buffer size=%d\n", lkst_init_buffer_size);
+	if (lkst_init_buffer_size < LKST_BUFFER_SIZE_MIN) {
+		printk(KERN_ERR "LKST warning(init): buffer size(=%d) is too small, changed to %d\n", lkst_init_buffer_size, LKST_BUFFER_SIZE_MIN);
+		lkst_init_buffer_size = LKST_BUFFER_SIZE_MIN;
+	} else if (lkst_init_buffer_size > LKST_BUFFER_SIZE_MAX) {
+		printk(KERN_ERR "LKST warning(init): buffer size(=%d) is too large, changed to %d\n", lkst_init_buffer_size, LKST_BUFFER_SIZE_MAX);
+		lkst_init_buffer_size = LKST_BUFFER_SIZE_MAX;
+	}
+
+	for (size = LKST_BUFFER_SIZE_MAX; size > lkst_init_buffer_size; size = size >> 1);
+	if (lkst_init_buffer_size != size)
+		printk(KERN_ERR "LKST warning(init): buffer size must be power of 2, changed to %d\n", size);
+	lkst_init_buffer_size = size;
+
+	lkst_trc_init_main();
+	return 0;
+}
+
+static void __exit lkst_cleanup_module(void)
+{
+	int i;
+
+	/* GKHI hook cleanup */
+	lkst_trc_hook_cleanup();
+
+	/* LKST initialize flag off */
+	lkst_init_flag = LKST_FLAG_NO;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+	unregister_sysrq_key('v', &sysrq_lkst_dump_buffer_op);
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+	lkst.current_maskset_id = LKST_MASKSET_ID_RNOTHING;
+	lkst.current_masksetp = 0;
+
+	memset(lkst.cpu_recid, 1, sizeof(lkst_cpu_recid)*LKST_CPU_RECID_BUF_SIZE);
+
+	/* Cleanup default maskset pointer */
+	LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table,
+				     LKST_MASKSET_ID_RALL, "", NULL);
+	LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table,
+				     LKST_MASKSET_ID_RNOTHING, "", NULL);
+	LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table,
+				     LKST_MASKSET_ID_RDEFAULT, "", NULL);
+
+	/* Cleanup additional maskset pointer & Free */
+	for (i = 3; i < LKST_MASKSET_TBL_MAX; i++) {
+		if (lkst.maskset_table[i].masksetp) {
+			vfree(lkst.maskset_table[i].masksetp);
+			LKST_MASKSET_TABLE_ENTRY_SET(lkst.maskset_table, i,
+						     "", NULL);
+		}
+	}
+
+	/* Cleanup event handler */
+	lkst_evhandler_register(LKST_EVHANDLER_ID_DEFAULT, "", NULL, NULL);
+	for (i = 0; i < LKST_EVHANDLER_TBL_MAX; i++) {
+		lkst_evhandler_register(i, "", NULL, NULL);
+	}
+
+	/* Cleanup event buffer_table & Deallcation event buffer */
+	lkst.buffer_table[0].bufferp = NULL;
+	for (i = 1; i < LKST_BUFFER_TBL_MAX; i++) {
+		if (lkst.buffer_table[i].bufferp) {
+			vfree(lkst.buffer_table[i].bufferp);
+			lkst.buffer_table[i].bufferp = NULL;
+		}
+	}
+
+	/* Cleanup current buffer */
+	for (i = 0; i < LKST_CPU_MAX; i++) {
+		lkst.buffer_head[i] = LKST_BUFFER_ID_VOID;
+		lkst.buffer_tail[i] = LKST_BUFFER_ID_VOID;
+		lkst.buffer_ring[i] = 0;
+	}
+
+	/* unregister LKST device file_operations */
+#ifdef CONFIG_DEVFS_FS
+	if (devfs_unregister_chrdev(LKST_DEV_MAJOR, LKST_DEV_NAME))
+#else
+	if (unregister_chrdev(LKST_DEV_MAJOR, LKST_DEV_NAME))
+#endif
+		printk(KERN_ERR "LKST error :cannot unregister LKST device!\n");
+
+#ifdef CONFIG_DEVFS_FS
+        devfs_unregister ( lkst_devfs_handle );
+#endif
+	/* deallocation complete */
+}
+
+module_init(lkst_init_module);
+module_exit(lkst_cleanup_module);
+MODULE_PARM(lkst_init_buffer_size, "i");
+MODULE_PARM_DESC(lkst_init_buffer_size, "Default size of each buffer(4096-0x200000, in power of 2)");
+#endif /* MODULE */
diff -Naur kernel.orig/linux24/fs/buffer.c kernel/linux24/fs/buffer.c
--- kernel.orig/linux24/fs/buffer.c	Sat Dec 22 02:41:55 2001
+++ kernel/linux24/fs/buffer.c	Fri Jun 28 20:57:45 2002
@@ -53,6 +53,8 @@
 #include <asm/bitops.h>
 #include <asm/mmu_context.h>
 
+#include <linux/lkst.h>
+
 #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
 #define NR_RESERVED (10*MAX_BUF_PER_PAGE)
 #define MAX_UNUSED_BUFFERS NR_RESERVED+20 /* don't ever have more than this 
@@ -143,6 +145,12 @@
 	struct task_struct *tsk = current;
 	DECLARE_WAITQUEUE(wait, tsk);
 
+	LKST_HOOK(LKST_ETYPE_FS_BUFBUSY,
+		       LKST_ARG32(bh, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	get_bh(bh);
 	add_wait_queue(&bh->b_wait, &wait);
 	do {
@@ -163,6 +171,12 @@
  */
 void end_buffer_io_sync(struct buffer_head *bh, int uptodate)
 {
+	LKST_HOOK(LKST_ETYPE_FS_DEVEND,
+		       LKST_ARG32(bh, 0),
+		       LKST_ARG32(uptodate, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	mark_buffer_uptodate(bh, uptodate);
 	unlock_buffer(bh);
 	put_bh(bh);
diff -Naur kernel.orig/linux24/include/asm-i386/hook.h kernel/linux24/include/asm-i386/hook.h
--- kernel.orig/linux24/include/asm-i386/hook.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/asm-i386/hook.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,209 @@
+#ifndef __ASM_I386_HOOK_H
+#define __ASM_I386_HOOK_H
+/*****************************************************************************/
+/* Kernel Hooks Interface.                                    		     */
+/* Version 1.2                                                               */
+/* Author: Richard J Moore richardj_moore@uk.ibm.com                         */
+/* 	   Vamsi Krishna S. r1vamsi@in.ibm.com 				     */
+/*                                                                           */
+/* Hooks optimized for the i386 architecture.				     */
+/*                                                                           */
+/* Refer to Documentation/hook/HOWTO for details.                            */
+/*****************************************************************************/
+#include <asm/pgtable.h>
+
+#if defined(CONFIG_HOOK) || defined(CONFIG_HOOK_MODULE)
+
+/* define a type 0 hook: 0 parameters */
+#define __HAVE_ASM_HOOK
+#define HOOK(h, args...) _HOOK(h, ##args)
+#define _HOOK(h, args...) __HOOK(#h, h, ##args)
+#define __HOOK(h, h1, args...) \
+{ \
+	register int tmp; \
+	__asm__ __volatile__ (".global "h"; "h":movl $0, %0":"=r"(tmp)); \
+	if (unlikely(tmp)) { \
+		{ \
+		register hook_rec_t *ptr; \
+		extern hook_head_t h1##_head; \
+		for (ptr = h1##_head.hook_next; \
+			!((ptr->hook_flags & HOOK_ARMED) && \
+			  ((*(hook_fn_t)(ptr->hook_exit))(ptr, ##args))); \
+			ptr = ptr->hook_next); \
+		} \
+	} \
+}
+
+/* define a conditional return hook with 0 parameters */
+#define __HAVE_ASM_HOOK_RET
+#define HOOK_RET(h, args...) _HOOK_RET(h, ##args)
+#define _HOOK_RET(h, args...) __HOOK_RET(#h, h, ##args)
+#define __HOOK_RET(h, h1, args...) \
+{ \
+	register int tmp; \
+	__asm__ __volatile__ (".global "h"; "h":movl $0, %0":"=r"(tmp)); \
+	if (unlikely(tmp)) { \
+		{ \
+		register hook_rec_t *ptr; \
+		int rc; \
+		register int dsprc; \
+		extern hook_head_t h1##_head; \
+		for (ptr = h1##_head.hook_next; \
+			!((ptr->hook_flags & HOOK_ARMED) && \
+			  (dsprc=(*(hook_fn_t)(ptr->hook_exit))(ptr, &rc, ##args))); \
+			ptr=ptr->hook_next); \
+		if (dsprc == HOOK_RETURN) return rc; \
+		} \
+	} \
+}
+
+/* define a conditional return hook with 1 parameter, no return value */
+#define __HAVE_ASM_HOOK_RET_NORC
+#define HOOK_RET_NORC(h, args...) _HOOK_RET_NORC(h, ##args)
+#define _HOOK_RET_NORC(h, args...) __HOOK_RET_NORC(#h, h, ##args)
+#define __HOOK_RET_NORC(h, h1, args...) \
+{ \
+	register int tmp; \
+	__asm__ __volatile__ (".global "h"; "h":movl $0, %0":"=r"(tmp)); \
+	if (unlikely(tmp)) { \
+		{ \
+		register hook_rec_t *ptr; \
+		register int dsprc; \
+		extern hook_head_t h1##_head; \
+		for (ptr = h1##_head.hook_next; \
+			!((ptr->hook_flags & HOOK_ARMED) && \
+			  (dsprc=(*(hook_fn_t)(ptr->hook_exit))(ptr, ##args))); \
+			ptr = ptr->hook_next); \
+	 	if (dsprc == HOOK_RETURN) return; \
+  		} \
+	} \
+}
+
+#define __HAVE_ASM_EXCLUSIVE_HOOK
+#define EXCLUSIVE_HOOK(h, args...) _EXCLUSIVE_HOOK(h, ##args)
+#define _EXCLUSIVE_HOOK(h, args...) __EXCLUSIVE_HOOK(#h, h, ##args)
+#define __EXCLUSIVE_HOOK(h, h1, args...) \
+{ \
+	register int tmp; \
+	__asm__ __volatile__ (".global "h"; "h":movl $0, %0":"=r"(tmp)); \
+	if (unlikely(tmp)) { \
+		{ \
+		extern hook_head_t h1##_head; \
+		(*(hook_fn_t)(h1##_head.hook_exit))(h1##_head.hook_next, ##args); \
+  		} \
+	} \
+}
+
+#define __HAVE_ASM_EXCLUSIVE_HOOK_RET
+#define EXCLUSIVE_HOOK_RET(h, args...) _EXCLUSIVE_HOOK_RET(h, ##args)
+#define _EXCLUSIVE_HOOK_RET(h, args...) __EXCLUSIVE_HOOK_RET(#h, h, ##args)
+#define __EXCLUSIVE_HOOK_RET(h, h1, args...) \
+{ \
+	register int tmp; \
+	__asm__ __volatile__ (".global "h"; "h":movl $0, %0":"=r"(tmp)); \
+	if (unlikely(tmp)) { \
+		{ \
+		int rc; \
+		register int dsprc; \
+		extern hook_head_t h1##_head; \
+		dsprc = (*(hook_fn_t)(h1##_head.hook_exit))(h1##_head.hook_next, &rc, ##args); \
+	 	if (dsprc == HOOK_RETURN) return rc; \
+  		} \
+	} \
+}
+
+/* define an exclusive conditional return hook with 1 parm, no return value */
+#define __HAVE_ASM_EXCLUSIVE_HOOK_RET_NORC
+#define EXCLUSIVE_HOOK_RET_NORC(h, args...) _EXCLUSIVE_HOOK_RET_NORC(h, ##args)
+#define _EXCLUSIVE_HOOK_RET_NORC(h, args...) __EXCLUSIVE_HOOK_RET_NORC(#h, h, ##args)
+#define __EXCLUSIVE_HOOK_RET_NORC(h, h1, args...) \
+{ \
+	register int tmp; \
+	__asm__ __volatile__ (".global "h"; "h":movl $0, %0":"=r"(tmp)); \
+	if (unlikely(tmp)) { \
+		{ \
+		extern hook_head_t h1##_head; \
+		register int dsprc = (*(hook_fn_t)(h1##_head.hook_exit))(h1##_head.hook_next, ##args); \
+	 	if (dsprc == HOOK_RETURN) return; \
+  		} \
+	} \
+}
+
+#endif /* CONFIG_HOOK || CONFIG_HOOK_MODULE */
+
+/* opcodes used for relative jump at Hook_bp*/
+#define JMP8_OPCODE 0xeb
+#define JMP32_OPCODE 0xe9
+
+/* offsets used for relative jump to bypass jmp dispatcher */
+#define JMP_NOP 0x0
+#define JMP8_BYPASS 0x2
+#define JMP32_BYPASS 0x05
+
+/*
+ * Sanity check the hook location for valid instructions at hook location.
+ * At hook location, we should find these instructions:
+ *	b9 00 00 00 00       	mov    $0x0,%ecx
+ *	85 c9                	test   %ecx,%ecx
+ * We can check for mov and test instructions. As these instructions encode
+ * the register name in them and the register cannot be predicted, we mask out
+ * the bits corresponding to registers in the opcode before comparing.
+ * 
+ * mov imm to reg
+ * 	1011 wreg
+ *	1100 011w : 1100 0reg (or)
+ * test reg1 reg2
+ * 	1000 010w : 11xx xyyy (xxx = reg1, yyy = reg2)
+ * 	
+ * v1.4: 10/04/2001
+ * Unfortunately, we can't be certain that the test instruction follows right
+ * after the mov, as the compiler could move some other code in between these
+ * two instructions. So, is_asm_hook checks only for "mov $0, reg" at the given
+ * hook location.
+ */
+#define OPCODE_MOV1			0xb0
+#define OPCODE_MOV1_MASK		0xf0
+#define OPCODE_MOV2_1			0xc6 /* first byte */
+#define OPCODE_MOV2_2			0xc0 /* second byte */
+#define OPCODE_MOV2_1_MASK		0xfe
+#define OPCODE_MOV2_2_MASK		0xf8
+#define OPCODE_TEST_1			0x84 /* first byte */
+#define OPCODE_TEST_2			0xc0 /* second byte */
+#define OPCODE_TEST_1_MASK		0xfe	
+#define OPCODE_TEST_2_MASK		0xc0	
+		
+static inline int is_asm_hook(unsigned char * phookloc)
+{
+	if(phookloc == NULL) return 0;
+	if((phookloc[0] & OPCODE_MOV1_MASK) == OPCODE_MOV1) {
+		if (*((unsigned long *)(phookloc+1)) == 0)
+			return 1;
+	} else if (((phookloc[0] & OPCODE_MOV2_1_MASK) == OPCODE_MOV2_1) && 
+		    ((phookloc[1] & OPCODE_MOV2_2_MASK) == OPCODE_MOV2_2)) {
+		if (*((unsigned long *)(phookloc+2)) == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static inline void deactivate_asm_hook(hook_head_t * phookhead)
+{
+	unsigned char *phook = (unsigned char *) (phookhead->hook_loc);
+	phook[2] = 0;
+	flush_icache_range(phook + 2, phook + 2);
+	return;
+}
+
+/*
+ *  we activate a hook by changing the bypass jump offset to 0 - this atomic
+ *  under MP
+ */
+static inline void activate_asm_hook(hook_head_t * phookhead)
+{
+	unsigned char *phook = (unsigned char *) (phookhead->hook_loc);
+	phook[2] = 1;
+	flush_icache_range(phook + 2, phook + 2);
+	return;
+}
+
+#endif /* __ASM_I386_HOOK_H */
diff -Naur kernel.orig/linux24/include/asm-i386/io.h kernel/linux24/include/asm-i386/io.h
--- kernel.orig/linux24/include/asm-i386/io.h	Fri Nov 23 04:46:27 2001
+++ kernel/linux24/include/asm-i386/io.h	Fri Jun 28 20:57:45 2002
@@ -3,6 +3,8 @@
 
 #include <linux/config.h>
 
+#include <linux/lkst.h>
+
 /*
  * This file contains the definitions for the x86 IO instructions
  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
@@ -249,14 +251,18 @@
 #ifdef CONFIG_MULTIQUAD
 /* Make the default portio routines operate on quad 0 for now */
 #define __OUT(s,s1,x) \
-__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
-__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
+__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); \
+LKST_ENTRY_LOG_PIO_OUT(port,sizeof(x),value,__builtin_return_address(0));} \
+__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));\
+LKST_ENTRY_LOG_PIO_OUT(port,sizeof(x),value,__builtin_return_address(0));} \
 __OUTQ0(s,s,x) \
 __OUTQ0(s,s##_p,x) 
 #else
 #define __OUT(s,s1,x) \
-__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
-__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} 
+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); \
+LKST_ENTRY_LOG_PIO_OUT(port,sizeof(x),value,__builtin_return_address(0))} \
+__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));\
+LKST_ENTRY_LOG_PIO_OUT(port,sizeof(x),value,__builtin_return_address(0));} 
 #endif /* CONFIG_MULTIQUAD */
 
 #ifdef CONFIG_MULTIQUAD
@@ -285,14 +291,22 @@
 
 #ifdef CONFIG_MULTIQUAD
 #define __IN(s,s1,i...) \
-__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); \
+LKST_ENTRY_LOG_PIO_IN(port,sizeof(_v),_v,__builtin_return_address(0));\
+return _v; } \
+__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); \
+LKST_ENTRY_LOG_PIO_IN(port,sizeof(_v),_v,__builtin_return_address(0));\
+return _v; } \
 __INQ0(s,s) \
 __INQ0(s,s##_p) 
 #else
 #define __IN(s,s1,i...) \
-__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } 
+__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); \
+LKST_ENTRY_LOG_PIO_IN(port,sizeof(_v),_v,__builtin_return_address(0));\
+return _v; } \
+__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); \
+LKST_ENTRY_LOG_PIO_IN(port,sizeof(_v),_v,__builtin_return_address(0));\
+return _v; } 
 #endif /* CONFIG_MULTIQUAD */
 
 #define __INS(s) \
diff -Naur kernel.orig/linux24/include/asm-i386/lkst.h kernel/linux24/include/asm-i386/lkst.h
--- kernel.orig/linux24/include/asm-i386/lkst.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/asm-i386/lkst.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,50 @@
+/* $Id: lkst.h,v 1.2 2002/03/25 19:05:13 serizawa Exp $ */
+/* linux/include/asm-i386/lkst.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by T.Nakamura <tetsu@crl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#ifndef _ARCH_I386_LKST_H
+#define _ARCH_I386_LKST_H
+
+#ifdef __KERNEL__
+#include <asm/timex.h>		/* for cpu_khz */
+#endif /* #ifndef __KERNEL__ */
+
+#define LKST_BIG_ENDIAN	0
+
+	//TODO: LKST_ARGP()'s shift
+	/* LKST_ARGP converts a pointer into lkst_arg_t. */
+#define LKST_ARGP_S(ptr)							\
+	((lkst_arg_t) ((unsigned int)(ptr) << 32))
+#define LKST_ARGP(ptr)							\
+	((lkst_arg_t) ((unsigned int)(ptr)))
+
+	/* This is ugly fix for arch/i386/boot/compressed/misc.c */
+#ifdef LKST_SUPPRESS_PIO_TRACE
+
+#define LKST_ENTRY_LOG_PIO_OUT(portaddr,bw,val,calladdr)
+#define LKST_ENTRY_LOG_PIO_IN(portaddr,bw,val,calladdr)
+
+#else  /* i.e., !ifdef LKST_SUPPRESS_PIO_TRACE */
+
+#define LKST_ENTRY_LOG_PIO_OUT(portaddr,bw,val,calladdr)\
+  LKST_HOOK_INLINE(LKST_ETYPE_O_PORTOUT, LKST_ARG32(portaddr,bw),\
+		LKST_ARG32(val,0), LKST_ARGP(calladdr), 0);
+#define LKST_ENTRY_LOG_PIO_IN(portaddr,bw,val,calladdr)\
+  LKST_HOOK_INLINE(LKST_ETYPE_O_PORTIN, LKST_ARG32(portaddr,bw),\
+		LKST_ARG32(val,0), LKST_ARGP(calladdr), 0);
+
+#endif /* ifdef LKST_SUPPRESS_PIO_TRACE */
+
+typedef	unsigned long	lkst_cpu_freq_t;
+typedef	u_int64_t 	lkst_tsc_t;
+
+#endif /* _ARCH_I386_LKST_H */
diff -Naur kernel.orig/linux24/include/asm-i386/lkst_private.h kernel/linux24/include/asm-i386/lkst_private.h
--- kernel.orig/linux24/include/asm-i386/lkst_private.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/asm-i386/lkst_private.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,80 @@
+/* $Id: lkst_private.h,v 1.3 2002/03/25 19:05:13 serizawa Exp $ */
+/* linux/include/asm-i386/lkst_private.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by T.Nakamura <tetsu@crl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#ifndef _ARCH_I386_LKST_PRIVATE_H
+#define _ARCH_I386_LKST_PRIVATE_H
+
+#include <asm/lkst.h>
+#include <asm/msr.h>
+
+typedef unsigned int lkst_pointer_check_digit;
+
+#define LKST_POINTER_CHECK_MAGIC	((lkst_pointer_check_digit)0x3c695a0f)
+
+
+/**
+ * atomic_read_and_inc - read and increment atomic variable
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically increments @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+
+static __inline__ int atomic_read_and_add(int i, atomic_t * v)
+{
+	__asm__ __volatile__(LOCK "xadd %1,%0":"+m"(v->counter), "=r"(i)
+			     :"0"(v->counter), "1"(i):"memory");
+	return (i);
+}
+
+
+/*
+ * function lkst_evhandlerprim_mc()
+ * A primitive part of an Event-handler. This function returns current
+ * value of machine-cycle-counter.
+ * 
+ *  Arguments
+ *    NONE
+ *
+ *  returns
+ *    tsc:	current value of machine-cycle-counter.
+ * 
+ */
+static __inline__ lkst_tsc_t lkst_evhandlerprim_mc(void)
+{
+	register lkst_tsc_t tsc;
+
+	/* Read the Time Stamp Counter */
+	rdtscll(tsc);
+	return tsc;
+}
+
+
+/*
+ * get variable "cpu_khz".
+ */
+#define	LKST_GET_CPU_KHZ() ((lkst_cpu_freq_t)cpu_khz)
+
+
+#define LKST_CLI(flags) {	\
+	__save_flags((flags));	\
+	__cli();}
+
+#define LKST_STI(flags) {	\
+	__restore_flags((flags));}
+
+
+#define LKST_LIMIT_ADDRESS_CHECK(buffer, size, limit)			\
+	(((void *) ((char *) buffer + size)) <= limit)
+
+#endif /* _ARCH_I386_LKST_PRIVATE_H */
diff -Naur kernel.orig/linux24/include/asm-i386/spinlock.h kernel/linux24/include/asm-i386/spinlock.h
--- kernel.orig/linux24/include/asm-i386/spinlock.h	Fri Nov 23 04:46:19 2001
+++ kernel/linux24/include/asm-i386/spinlock.h	Fri Jun 28 20:57:45 2002
@@ -5,6 +5,7 @@
 #include <asm/rwlock.h>
 #include <asm/page.h>
 #include <linux/config.h>
+#include <linux/lkst.h>
 
 extern int printk(const char * fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
@@ -85,6 +86,11 @@
 	if (!spin_is_locked(lock))
 		BUG();
 #endif
+#ifndef _IN_LINUX_LKST_H
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_SPINUNLOCK,
+		LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(lock,0),
+		LKST_ARG32(0,0), LKST_ARG32(0,0));
+#endif /* !_IN_LINUX_LKST_H */
 	__asm__ __volatile__(
 		spin_unlock_string
 	);
@@ -106,6 +112,11 @@
 	if (!spin_is_locked(lock))
 		BUG();
 #endif
+#ifndef _IN_LINUX_LKST_H
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_SPINUNLOCK,
+		LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(lock,0),
+		LKST_ARG32(0,0), LKST_ARG32(0,0));
+#endif /* !_IN_LINUX_LKST_H */
 	__asm__ __volatile__(
 		spin_unlock_string
 	);
@@ -120,6 +131,11 @@
 		"xchgb %b0,%1"
 		:"=q" (oldval), "=m" (lock->lock)
 		:"0" (0) : "memory");
+#ifndef _IN_LINUX_LKST_H
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_SPINTRYLOCK,
+		LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(lock,0),
+		LKST_ARG32((oldval > 0),0), LKST_ARG32(0, 0));
+#endif /* !_IN_LINUX_LKST_H */
 	return oldval > 0;
 }
 
@@ -133,6 +149,11 @@
 		BUG();
 	}
 #endif
+#ifndef _IN_LINUX_LKST_H
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_SPINLOCK,
+		       LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(lock,0),
+		       LKST_ARG32(0,0), LKST_ARG32(0,0));
+#endif /* !_IN_LINUX_LKST_H */
 	__asm__ __volatile__(
 		spin_lock_string
 		:"=m" (lock->lock) : : "memory");
@@ -185,6 +206,11 @@
 	if (rw->magic != RWLOCK_MAGIC)
 		BUG();
 #endif
+#ifndef _IN_LINUX_LKST_H
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_RDLOCK,
+		       LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(rw,0),
+		       LKST_ARG32(0,0), LKST_ARG32(0,0));
+#endif /* !_IN_LINUX_LKST_H */
 	__build_read_lock(rw, "__read_lock_failed");
 }
 
@@ -194,19 +220,57 @@
 	if (rw->magic != RWLOCK_MAGIC)
 		BUG();
 #endif
+#ifndef _IN_LINUX_LKST_H
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_WRLOCK,
+		       LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(rw,0),
+		       LKST_ARG32(0,0), LKST_ARG32(0,0));
+#endif /* !_IN_LINUX_LKST_H */
 	__build_write_lock(rw, "__write_lock_failed");
 }
 
+#if (defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)) && !defined(_IN_LINUX_LKST_H)
+#define read_unlock(rw)		{	\
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_RDUNLOCK, \
+		LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(rw,0), \
+		LKST_ARG32(0,0), LKST_ARG32(0,0));\
+	asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory"); }
+#else /* !CONFIG_DEBUG_KERNEL_STATE_TRACE || _IN_LINUX_LKST_H */
 #define read_unlock(rw)		asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE && !_IN_LINUX_LKST_H */
+
+#if (defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)) && !defined(_IN_LINUX_LKST_H)
+#define write_unlock(rw)		{	\
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_WRUNLOCK, \
+		LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(rw,0), \
+		LKST_ARG32(0,0), LKST_ARG32(0,0)); \
+	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory"); }
+#else /* !CONFIG_DEBUG_KERNEL_STATE_TRACE || _IN_LINUX_LKST_H */
 #define write_unlock(rw)	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE && !_IN_LINUX_LKST_H */
 
 static inline int write_trylock(rwlock_t *lock)
 {
 	atomic_t *count = (atomic_t *)lock;
+#if (defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) || defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)) && !defined(_IN_LINUX_LKST_H)
+	int	locked = 0;
+
+	if (atomic_sub_and_test(RW_LOCK_BIAS, count)) {
+		locked	= 1;
+	}
+	else {
+		atomic_add(RW_LOCK_BIAS, count);
+		locked	= 0;
+	}
+	LKST_HOOK_INLINE(LKST_ETYPE_LK_WRTRYLOCK,
+		LKST_ARG32(lkst_current_pc(),0), LKST_ARG32(lock,0),
+		LKST_ARG32(locked,0), LKST_ARG32(0,0));
+	return (locked);
+#else /* !CONFIG_DEBUG_KERNEL_STATE_TRACE || _IN_LINUX_LKST_H */
 	if (atomic_sub_and_test(RW_LOCK_BIAS, count))
 		return 1;
 	atomic_add(RW_LOCK_BIAS, count);
 	return 0;
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE && !_IN_LINUX_LKST_H */
 }
 
 #endif /* __ASM_SPINLOCK_H */
diff -Naur kernel.orig/linux24/include/linux/hook.h kernel/linux24/include/linux/hook.h
--- kernel.orig/linux24/include/linux/hook.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/linux/hook.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,304 @@
+#ifndef __LINUX_HOOK_H
+#define __LINUX_HOOK_H
+/*****************************************************************************/
+/* Kernel Hooks Interface.                                    		     */
+/* Version 1.2                                                               */
+/* Author: Richard J Moore richardj_moore@uk.ibm.com                         */
+/* 	   Vamsi Krishna S. r1vamsi@in.ibm.com 				     */
+/*                                                                           */
+/* Kernel hook interface definitions and arch-independent hooks.	     */
+/*                                                                           */
+/* Refer to Documentation/hook/HOWTO for details.                            */
+/*****************************************************************************/
+#include <linux/compiler.h>
+#include <linux/module.h>
+
+/*
+ * Use the DECLARE_HOOK_HEAD macro to define the hookhead structure in global 
+ * memory of a kernel module that is implementing a hook.
+ */
+#if defined(CONFIG_HOOK) || defined(CONFIG_HOOK_MODULE)
+#define DECLARE_HOOK_HEAD(x) _DECLARE_HOOK_HEAD(x)
+#define _DECLARE_HOOK_HEAD(hk) \
+char hk ## _id[sizeof(#hk)] = #hk; \
+extern void hk; \
+hook_head_t hk ## _head = { \
+	hook_head: &(hk##_head), \
+	hook_loc: &(hk), \
+	hook_id: hk##_id \
+}; \
+EXPORT_SYMBOL(hk ## _head); \
+extern hook_head_t hk ## _head
+
+#define DECLARE_EXCLUSIVE_HOOK_HEAD(x) _DECLARE_EXCLUSIVE_HOOK_HEAD(x)
+#define _DECLARE_EXCLUSIVE_HOOK_HEAD(hk) \
+char hk ## _id[sizeof(#hk)] = #hk; \
+extern void hk; \
+hook_head_t hk ## _head = { \
+	hook_head: &(hk##_head), \
+	hook_loc: &(hk), \
+	hook_id: hk##_id, \
+	hook_flags: HOOK_HEAD_EXCLUSIVE \
+}; \
+EXPORT_SYMBOL_NOVERS(hk ## _head); \
+extern hook_head_t hk ## _head
+
+#define USE_HOOK(x) _USE_HOOK(x)
+#define _USE_HOOK(hk) extern hook_head_t hk ## _head
+#else
+#define DECLARE_HOOK_HEAD(x)
+#define USE_HOOK(x)
+#endif
+
+/* define the user (kernel module) hook structure */
+struct hook_rec_s;
+struct hook_head_s;
+
+typedef struct hook_rec_s {
+	void * hook_exit;
+	char * hook_exit_name;
+	struct hook_rec_s * hook_next;
+	struct hook_rec_s * hook_prev;
+	unsigned int hook_flags;
+	struct hook_rec_s * hook_link;
+	struct hook_head_s * hook_head;
+	unsigned int hook_index;
+	struct proc_dir_entry *proc_entry;
+	int proc_writable;
+} hook_rec_t;
+
+typedef struct hook_head_s {
+	void * hook_exit;
+	char * hook_exit_name;
+	struct hook_rec_s * hook_next;
+	struct hook_rec_s * hook_prev;
+	unsigned int hook_flags;
+	struct hook_rec_s * hook_link;
+	struct hook_head_s * hook_head;
+	unsigned int hook_index;
+	struct proc_dir_entry *proc_entry;
+	struct hook_head_s * hook_head_next;
+	void * hook_loc;
+	char * hook_id;
+} hook_head_t;
+
+/* hook flags */
+#define HOOK_ARMED		0x00000001
+#define HOOK_REGISTERED		0x00000002
+#define HOOK_PRIORITY_FIRST	0x00000004
+#define HOOK_PRIORITY_LAST	0x00000008
+#define HOOK_PRIORITY_EXCLUSIVE	0x0000000c
+#define HOOK_QUEUE_LIFO		0x00000010
+
+/* the following are reserved for future enhancement */
+#define HOOK_OPTION_DISABLE_IRQS	0x00001000
+#define HOOK_OPTION_STOP_CPUS		0x00002000
+
+
+/* flag groupings */
+#define HOOK_STATUS		(HOOK_ARMED | HOOK_REGISTERED)
+#define HOOK_PRIORITY		(HOOK_PRIORITY_FIRST | HOOK_PRIORITY_LAST)
+#define HOOK_QUEUE		HOOK_QUEUE_LIFO
+#define HOOK_OPTIONS		(HOOK_OPTION_DISABLE_IRQS | HOOK_OPTION_STOP_CPUS)
+#define HOOK_VALID_USER_FLAGS	(HOOK_PRIORITY | HOOK_QUEUE | HOOK_OPTIONS)
+
+#ifndef FLASE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE !FALSE
+#endif
+
+/* exported functions wrapped in a macro */
+int _hook_initialise(hook_head_t *);
+int _hook_terminate(hook_head_t *, int);
+int _hook_exit_register(char *, hook_rec_t *, int proc_writable);
+
+/* exported functions error codes */
+#define NO_ERROR 				 0
+#define ERROR_HOOK_NOT_FOUND 			-1
+#define ERROR_HIGHER_PRIORITY_HOOK 		-2
+#define ERROR_INVALID_REGISTRATION_RECORD 	-3
+#define ERROR_LOWER_PRIORITY_HOOK 		-4
+#define ERROR_GKHI_UNAVAILABLE 			-5
+#define ERROR_INVALID_HOOK_LOCATION 		-6
+#define ERROR_HOOK_EXISTS 			-7
+#define ERROR_HOOK_IS_ACTIVE 			-8
+
+/* Return values from Hook Exit routines */
+#define HOOK_CONTINUE 	0
+#define HOOK_TERMINATE 	1
+#define HOOK_RETURN 	-1
+
+/* exported function prototypes */
+int hook_exit_deregister(hook_rec_t *);
+int hook_exit_arm(hook_rec_t *);
+int hook_exit_disarm(hook_rec_t *);
+
+/*
+ * public interfaces requiring a macro wrapper
+ *
+ * int hook_exit_register(hookid, hook_rec_t *);
+ * int hook_terminate(hookid, int force_flag);/
+ * int hook_initialise(hookid);
+ *
+ * where hookid is a typeless name
+ */
+#define hook_exit_register(x, y, z) dummy_hook_exit_register(x, y, z)
+#define dummy_hook_exit_register(x, y, z) _hook_exit_register(#x, y, z)
+#define hook_terminate(x, y) dummy_hook_terminate(x, y)
+#define dummy_hook_terminate(x, y) _hook_terminate(&(x ## _head), y)
+#define hook_initialise(x) dummy_hook_initialise(x)
+#define dummy_hook_initialise(x) _hook_initialise(&(x ## _head))
+
+/* define head record only flags */
+#define HOOK_HEAD_ACTIVE	0x80000000
+#define HOOK_HEAD_ASM_HOOK	0x40000000
+#define HOOK_HEAD_EXCLUSIVE	0x20000000
+#define HOOK_HEAD_VALID_FLAGS	(HOOK_VALID_USER_FLAGS | HOOK_STATUS | HOOK_HEAD_ACTIVE | HOOK_HEAD_ASM_HOOK | HOOK_HEAD_EXCLUSIVE)
+
+/* global status flags */
+#define HOOK_INIT       0x00000001
+#define HOOK_IN_START   0x00000002
+
+#ifdef HOOK_DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: "fmt, __FUNCTION__, ##args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+typedef int (*hook_fn_t)(hook_rec_t *, ...);
+#include <asm/hook.h>
+
+#if defined(CONFIG_HOOK) || defined(CONFIG_HOOK_MODULE)
+#ifndef __HAVE_ASM_HOOK
+#define HOOK(h, args...) _HOOK(h, ##args)
+#define _HOOK(h, args...) __HOOK(#h, h, ##args)
+#define __HOOK(h, h1, args...) \
+	__asm__ __volatile__ (".global "h"; "h":"); \
+	if (unlikely(h1##_head.hook_flags & HOOK_HEAD_ACTIVE)) { \
+		register hook_rec_t *ptr; \
+		extern hook_head_t h1##_head; \
+		for (ptr = h1##_head.hook_next; \
+			!((ptr->hook_flags & HOOK_ARMED) && \
+			  ((*(hook_fn_t)(ptr->hook_exit))(ptr, ##args))); \
+			ptr = ptr->hook_next); \
+	}
+#endif /* __HAVE_ASM_HOOK */
+
+#ifndef __HAVE_ASM_HOOK_RET
+#define HOOK_RET(h, args...) _HOOK_RET(h, ##args)
+#define _HOOK_RET(h, args...) __HOOK_RET(#h, h, ##args)
+#define __HOOK_RET(h, h1, args...) \
+	__asm__ __volatile__ (".global "h"; "h":"); \
+	if (unlikely(h1##_head.hook_flags & HOOK_HEAD_ACTIVE)) { \
+		typedef int (*f)(hook_rec_t *, int *, ...); \
+		register hook_rec_t *ptr; \
+		int rc; \
+		register int dsprc; \
+		extern hook_head_t h1##_head; \
+		for (ptr = h1##_head.hook_next; \
+			!((ptr->hook_flags & HOOK_ARMED) && \
+			  (dsprc=(*(hook_fn_t)(ptr->hook_exit))(ptr, &rc, ##args))); \
+			ptr=ptr->hook_next); \
+		if (dsprc == HOOK_RETURN) return rc; \
+	}
+#endif /* __HAVE_ASM_HOOK_RET */
+
+#ifndef __HAVE_ASM_HOOK_RET_NORC
+#define HOOK_RET_NORC(h, args...) _HOOK_RET_NORC(h, ##args)
+#define _HOOK_RET_NORC(h, args...) __HOOK_RET_NORC(#h, h, ##args)
+#define __HOOK_RET_NORC(h, h1, args...) \
+	__asm__ __volatile__ (".global "h"; "h":"); \
+	if (unlikely(h1##_head.hook_flags & HOOK_HEAD_ACTIVE)) { \
+		typedef int (*f)(hook_rec_t *, ...); \
+		register hook_rec_t *ptr; \
+		register int dsprc; \
+		extern hook_head_t h1##_head; \
+		for (ptr = h1##_head.hook_next; \
+			!((ptr->hook_flags & HOOK_ARMED) && \
+			  (dsprc=(*(hook_fn_t)(ptr->hook_exit))(ptr, ##args))); \
+			ptr = ptr->hook_next); \
+	 	if (dsprc == HOOK_RETURN) return; \
+	}
+#endif /* __HAVE_ASM_HOOK_RET_NORC */
+
+#ifndef __HAVE_ASM_EXCLUSIVE_HOOK
+#define EXCLUSIVE_HOOK(h, args...) _EXCLUSIVE_HOOK(h, ##args)
+#define _EXCLUSIVE_HOOK(h, args...) __EXCLUSIVE_HOOK(#h, h, ##args)
+#define __EXCLUSIVE_HOOK(h, h1, args...) \
+	__asm__ __volatile__ (".global "h"; "h":"); \
+	if (unlikely(h1##_head.hook_flags & HOOK_HEAD_ACTIVE)) { \
+		typedef int (*f)(hook_rec_t *, ...); \
+		extern hook_head_t h1##_head; \
+		(*(hook_fn_t)(h1##_head.hook_exit))(h1##_head.hook_next, ##args); \
+	}
+#endif /* __EXCLUSIVE_HAVE_ASM_HOOK*/
+
+#ifndef __HAVE_ASM_EXCLUSIVE_HOOK_RET
+#define EXCLUSIVE_HOOK_RET(h, args...) _EXCLUSIVE_HOOK_RET(h, ##args)
+#define _EXCLUSIVE_HOOK_RET(h, args...) __EXCLUSIVE_HOOK_RET(#h, h, ##args)
+#define __EXCLUSIVE_HOOK_RET(h, h1, args...) \
+	__asm__ __volatile__ (".global "h"; "h":"); \
+	if (unlikely(h1##_head.hook_flags & HOOK_HEAD_ACTIVE)) { \
+		typedef int (*f)(int *); \
+		int rc; \
+		register int dsprc; \
+		extern hook_head_t h1##_head; \
+		dsprc = (*(hook_fn_t)(h1##_head.hook_exit))(h1##_head.hook_next, &rc, ##args); \
+		if (dsprc == HOOK_RETURN) return rc; \
+	}
+#endif /* __EXCLUSIVE_HAVE_ASM_HOOK_RET */
+
+#ifndef __HAVE_ASM_EXCLUSIVE_HOOK_RET_NORC
+#define EXCLUSIVE_HOOK_RET_NORC(h, args...) _EXCLUSIVE_HOOK_RET_NORC(h, ##args)
+#define _EXCLUSIVE_HOOK_RET_NORC(h, args...) __EXCLUSIVE_HOOK_RET_NORC(#h, h, ##args)
+#define __EXCLUSIVE_HOOK_RET_NORC(h, h1, args...) \
+	__asm__ __volatile__ (".global "h"; "h":"); \
+	if (unlikely(h1##_head.hook_flags & HOOK_HEAD_ACTIVE)) { \
+		typedef int (*f)(void *); \
+		extern hook_head_t h1##_head; \
+		register int dsprc = (*(hook_fn_t)(h1##_head.hook_exit))(h1##_head.hook_next, ##args); \
+		if (dsprc == HOOK_RETURN) return; \
+	}
+#endif /* __HAVE_ASM_EXCLUSIVE_HOOK_RET_NORC */
+
+/*
+ *  Generic hooks are the same in all architectures and may be used to
+ *  place hooks even in inline functions. They don't define a symbol at hook
+ *  location.
+ */ 
+#define DECLARE_GENERIC_HOOK_HEAD(x) _DECLARE_GENERIC_HOOK_HEAD(x)
+#define _DECLARE_GENERIC_HOOK_HEAD(hk) \
+char hk ## _id[sizeof(#hk)] = #hk; \
+hook_head_t hk ## _head = { \
+	hook_head: &(hk##_head), \
+	hook_loc: NULL, \
+	hook_id: hk##_id \
+}; \
+EXPORT_SYMBOL(hk ## _head); \
+extern hook_head_t hk ## _head
+
+#define GENERIC_HOOK(h, args...) _GENERIC_HOOK(h, ##args)
+#define _GENERIC_HOOK(h, args...) __GENERIC_HOOK(#h, h, ##args)
+#define __GENERIC_HOOK(h, h1, args...) { \
+	extern hook_head_t h1##_head; \
+	if (unlikely(h1##_head.hook_flags & HOOK_HEAD_ACTIVE)) { \
+		register hook_rec_t *ptr; \
+		for (ptr = h1##_head.hook_next; \
+			!((ptr->hook_flags & HOOK_ARMED) && \
+			  ((*(hook_fn_t)(ptr->hook_exit))(ptr, ##args))); \
+			ptr = ptr->hook_next); \
+	} \
+}
+#else
+/* dummy macros when hooks are not compiled in */
+#define HOOK(h, args...)
+#define HOOK_RET(h, args...)
+#define HOOK_RET_NORC(h, args...)
+#define EXCLUSIVE_HOOK(h, args...)
+#define EXCLUSIVE_HOOK_RET(h, args...)
+#define EXCLUSIVE_HOOK_RET_NORC(h, args...)
+#endif
+
+#endif /* __LINUX_HOOK_H */
diff -Naur kernel.orig/linux24/include/linux/lkst.h kernel/linux24/include/linux/lkst.h
--- kernel.orig/linux24/include/linux/lkst.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/linux/lkst.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,244 @@
+/* $Id: lkst.h,v 1.9 2002/04/25 12:48:07 indoh Exp $ */
+/* linux/include/linux/lkst.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by K.SERIZAWA <serizawa@sdl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#ifndef _LINUX_LKST_H
+#define _LINUX_LKST_H
+
+/* event types */
+#include <linux/lkst_events.h>
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#define _IN_LINUX_LKST_H
+#include <linux/hook.h>
+#undef _IN_LINUX_LKST_H
+#endif				/* __KERNEL__ */
+#include <linux/threads.h>
+#include <linux/ioctl.h>
+
+#include <asm/lkst.h>
+
+/* ioctl requests */
+#define LKST_IOC_MAGIC			'l'
+#define LKST_IOC_TRC_STATUS		_IO(LKST_IOC_MAGIC, 1)
+#define LKST_IOC_TRC_START		_IO(LKST_IOC_MAGIC, 2)
+#define LKST_IOC_TRC_STOP		_IO(LKST_IOC_MAGIC, 3)
+
+#define LKST_IOC_MASKSET_READ		_IO(LKST_IOC_MAGIC, 4)
+#define LKST_IOC_MASKSET_WRITE		_IO(LKST_IOC_MAGIC, 5)
+#define LKST_IOC_MASKSET_SET		_IO(LKST_IOC_MAGIC, 6)
+#define LKST_IOC_MASKSET_LIST		_IO(LKST_IOC_MAGIC, 7)
+#define LKST_IOC_MASKSET_DELETE		_IO(LKST_IOC_MAGIC, 8)
+
+#define LKST_IOC_EVHANDLER_LIST		_IO(LKST_IOC_MAGIC, 9)
+#define LKST_IOC_EVHANDLER_CTRL		_IO(LKST_IOC_MAGIC, 10)
+
+#define LKST_IOC_BUFFER_READ		_IO(LKST_IOC_MAGIC, 11)
+#define LKST_IOC_BUFFER_SEEK		_IO(LKST_IOC_MAGIC, 12)
+#define LKST_IOC_BUFFER_CREATE		_IO(LKST_IOC_MAGIC, 13)
+#define LKST_IOC_BUFFER_SHIFT		_IO(LKST_IOC_MAGIC, 14)
+#define LKST_IOC_BUFFER_DELETE		_IO(LKST_IOC_MAGIC, 15)
+#define LKST_IOC_BUFFER_LIST		_IO(LKST_IOC_MAGIC, 16)
+#define LKST_IOC_BUFFER_RING		_IO(LKST_IOC_MAGIC, 17)
+#define LKST_IOC_BUFFER_SETRMOD		_IO(LKST_IOC_MAGIC, 18)
+
+#define LKST_IOC_ENTRY_LOG		_IO(LKST_IOC_MAGIC, 19)
+
+/* Maskset to record no event */
+#define LKST_MASKSET_ID_RNOTHING	0
+/* Maskset to record all events */
+#define LKST_MASKSET_ID_RALL	1
+/* Maskset to record events specified when kernel compilation */
+#define LKST_MASKSET_ID_RDEFAULT	2
+
+/* LKST_MASKSET_TBL_MAX means size of maskset_table. (cf. LKST_MASKSET_TBL_LEN_MAX */
+#define LKST_MASKSET_TBL_MAX	((lkst_maskset_id) 0xFF)
+#define LKST_MASKSET_ID_MAX	((lkst_maskset_id) (LKST_MASKSET_TBL_MAX - 1))
+#define LKST_MASKSET_ID_VOID	((lkst_maskset_id) (LKST_MASKSET_ID_MAX + 1))
+
+#define LKST_EVHANDLER_TBL_MAX			((lkst_evhandler_id) 0xFF)
+#define LKST_EVHANDLER_ID_MAX						\
+	((lkst_evhandler_id) (LKST_EVHANDLER_TBL_MAX - 1))
+#define LKST_EVHANDLER_ID_VOID						\
+	((lkst_evhandler_id) (LKST_EVHANDLER_ID_MAX + 1))
+
+/* Definitions of event-handler ID.
+ *	EVHANDLER_ID_DMX:		for Dynamic Maskset eXchange
+ *	EVHANDLER_ID_DEFAULT:		default event-handler
+ *	EVHANDLER_ID_BUFFER_SHIFT:	shift buffers on buffer-overflow
+ *	EVHANDLER_ID_BUFFER_SHIFT_DW:	shift buffers and Wakeup LKST Daemon
+ *	EVHANDLER_ID_EXCEPTION:		for debug of exception loop
+ *	EVHANDLER_ID_MASKSET_XCHG:	do dynamic maskset exchange
+ */
+#define LKST_EVHANDLER_ID_DMX 			((lkst_evhandler_id) 0x00)
+#define LKST_EVHANDLER_ID_DEFAULT		((lkst_evhandler_id) 0x01)
+#define LKST_EVHANDLER_ID_BUFFER_SHIFT		((lkst_evhandler_id) 0x02)
+#define LKST_EVHANDLER_ID_BUFFER_SHIFT_DW	((lkst_evhandler_id) 0x03)
+#define LKST_EVHANDLER_ID_EXCEPTION		((lkst_evhandler_id) 0x04)
+#define LKST_EVHANDLER_ID_MASKSET_XCHG		((lkst_evhandler_id) 0x05)
+
+#define LKST_BUFFER_TBL_MAX	((lkst_buffer_id) 0xFF)
+#define LKST_BUFFER_ID_MAX	((lkst_buffer_id) (LKST_BUFFER_TBL_MAX - 1))
+#define LKST_BUFFER_ID_VOID	((lkst_buffer_id) (LKST_BUFFER_ID_MAX + 1))
+
+/* Max number of CPUs */
+#define LKST_CPU_MAX	32
+
+/* LKST availabe memory size -- must be power of 2 */
+#define LKST_AVAILABLE_MEMORY_SIZE	134217728	/* 128MB */
+
+typedef u_int64_t lkst_arg_t;
+#define LKST_ARG32(high,low)						\
+	((lkst_arg_t) (((lkst_arg_t) (unsigned int) high << 32) |	\
+		           (unsigned int) low))
+
+typedef unsigned char lkst_maskset_id;
+typedef unsigned char lkst_buffer_id;
+
+struct lkst_status_param {
+	lkst_maskset_id	current_maskset_id;
+				/* current selected maskset ID */
+	lkst_buffer_id	current_buffer_id[LKST_CPU_MAX];
+				/* current selected buffer ID */
+	int	maskset_num;	/* total number of registered masksets */
+	int	evhandler_num;	/* total number of registered event handlers */
+	int	buffer_num;	/* total number of created event buffers */
+};
+
+struct lkst_entry_args {
+	int event_type;		/* corresponding event type */	
+	lkst_arg_t arg1;	/* 1st argument acquired at a trace point */
+	lkst_arg_t arg2;	/* 2nd argument acquired at a trace point */
+	lkst_arg_t arg3;	/* 3rd argument acquired at a trace point */
+	lkst_arg_t arg4;	/* 4th argument acquired at a trace point */
+};
+
+				/* Array of mnemonics of event types */
+extern char *lkst_event_type_mnemonics[];
+				/* Array of descriptions of event types */
+extern char *lkst_event_type_descriptions[];
+
+extern void lkst_entry_log(void *phookrec, int event_type,
+			   lkst_arg_t arg1,
+			   lkst_arg_t arg2,
+			   lkst_arg_t arg3,
+			   lkst_arg_t arg4);
+
+extern void lkst_trc_init_stage0(void);
+
+extern void lkst_trc_init_stage1(void);
+
+extern void lkst_trc_init_main(void);
+
+extern void lkst_time_set(int from_settimeofday);
+
+extern int lkst_trc_status(struct lkst_status_param *param);
+
+extern int lkst_trc_start(void);
+
+extern int lkst_trc_stop(void);
+
+extern int lkst_maskset_xchg(lkst_maskset_id * id);
+
+extern __inline__ void lkst_dummy_vmalloc(void);
+
+static inline void * lkst_current_pc(void)
+{
+	__label__ here;
+here:
+	return (&&here);
+}
+
+				/* For IO trace */
+#if (!defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) && !defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)) || defined(CONFIG_HOOK) || defined(CONFIG_HOOK_MODULE) 
+#define LKST_SUPPRESS_PIO_TRACE
+#endif /* if (!defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) && !defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)) || defined(CONFIG_HOOK) || defined(CONFIG_HOOK_MODULE)  */
+
+				/* For GKHI */
+#ifdef __KERNEL__
+
+/* HOOK Information table */
+struct lkst_hook_info {
+	char* hook_id;
+	hook_rec_t* phookrec;
+};
+extern struct lkst_hook_info lkst_hook_info_table[];
+extern void lkst_hook_init_module(lkst_event_type etype);
+extern void lkst_hook_reset_all(void);
+
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+
+/* HOOK Interface */
+#define LKST_HOOK(etype, arg1, arg2, arg3, arg4) HOOK(etype##_HEADER, etype, arg1, arg2, arg3, arg4)
+#define LKST_HOOK_INLINE(etype, arg1, arg2, arg3, arg4) GENERIC_HOOK(etype##_HEADER, etype, arg1, arg2, arg3, arg4)
+
+/* Declaration of hook header */
+#define LKST_HOOK_DECLARE(etype) \
+	DECLARE_HOOK_HEAD(etype##_HEADER);	\
+	hook_rec_t etype##_hook_rec;
+
+#define LKST_HOOK_DECLARE_INLINE(etype) \
+	DECLARE_GENERIC_HOOK_HEAD(etype##_HEADER);	\
+	hook_rec_t etype##_hook_rec;
+
+/* Initialization of hook header */
+#define LKST_HOOK_INIT(etype, ret) \
+	_LKST_HOOK_INIT(etype, etype##_HEADER, etype##_hook_rec, ret)
+
+#define _LKST_HOOK_INIT(etype, hookid, hookrec, ret) ({ \
+	ret = hook_initialise(hookid);                      \
+	lkst_hook_info_table[etype].hook_id = #hookid;      \
+	lkst_hook_info_table[etype].phookrec = &hookrec;    \
+	memset(&hookrec, 0, sizeof(hook_rec_t));            \
+})
+
+/* Cleanup of hook header */
+#define LKST_HOOK_TERMINATE(etype, ret) \
+	_LKST_HOOK_TERMINATE(etype, etype##_HEADER, etype##_hook_rec, ret)
+
+#define _LKST_HOOK_TERMINATE(etype, hookid, hookrec, ret) ({  \
+	hook_exit_deregister(&hookrec);                           \
+	ret = hook_terminate(hookid, 0);                          \
+	lkst_hook_info_table[etype].hook_id = NULL;               \
+	lkst_hook_info_table[etype].phookrec = NULL;              \
+	memset(&hookrec, 0, sizeof(hook_rec_t));                  \
+})
+
+/* Initialization of hook header for module */
+#define LKST_HOOK_INIT_MODULE(etype, ret) \
+	_LKST_HOOK_INIT_MODULE(etype, etype##_HEADER, etype##_hook_rec, ret)
+
+#define _LKST_HOOK_INIT_MODULE(etype, hookid, hookrec, ret) ({ \
+	ret = hook_initialise(hookid);                             \
+	lkst_hook_info_table[etype].hook_id = #hookid;             \
+	lkst_hook_info_table[etype].phookrec = &hookrec;           \
+	lkst_hook_init_module(etype);                              \
+})
+
+/* Cleanup of hook header for module */
+#define LKST_HOOK_TERMINATE_MODULE(etype, ret) \
+	_LKST_HOOK_TERMINATE(etype, etype##_HEADER, etype##_hook_rec, ret)
+
+#else  /* !CONFIG_DEBUG_KERNEL_STATE_TRACE && !CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
+/* dummy macros when LKST is not compiled in */
+#define LKST_HOOK(etype, arg1, arg2, arg3, arg4)
+#define LKST_HOOK_INLINE(etype, arg1, arg2, arg3, arg4)
+#define LKST_HOOK_DECLARE(etype)
+#define LKST_HOOK_DECLARE_INLINE(etype)
+#define LKST_HOOK_INIT(etype, ret)
+#define LKST_HOOK_TERMINATE(etype, ret)
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
+
+#endif /* __KERNEL__ */
+
+#endif				/* _LINUX_LKST_H */
diff -Naur kernel.orig/linux24/include/linux/lkst_buffer.h kernel/linux24/include/linux/lkst_buffer.h
--- kernel.orig/linux24/include/linux/lkst_buffer.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/linux/lkst_buffer.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,199 @@
+/* $Id: lkst_buffer.h,v 1.8 2002/06/28 11:27:55 indoh Exp $ */
+/* linux/include/linux/lkst_buffer.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by K.HATASAKI <keisukeh@crl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#ifndef _LINUX_LKST_BUFFER_H
+#define _LINUX_LKST_BUFFER_H
+
+
+#include <linux/lkst.h>
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/time.h>
+#else /* #ifndef __KERNEL__ */
+#include <pthread.h>
+#include <sys/time.h>
+#endif	/* __KERNEL__ */
+
+		/* mode for ioctl(LKST_IOC_BUFFER_SETRMOD) command */
+#define RAW	0x01
+#define STD	0x02
+#define SORTED	0x04
+
+		/* size of lkst_event_record. It must be power of 2 */
+		/* This value will be verified in initialization of 
+		   LKST in DEBUG mode. */
+#define LKST_SIZEOF_LKST_EVENT_RECORD	(64)
+
+		/* 
+		 *  following 4 lines should be deleted
+		 *  if they has been already defined. 
+		 */
+typedef int posix_log_recid_t;
+typedef int posix_log_facility_t;
+typedef int posix_log_severity_t;
+typedef int posix_log_procid_t;
+
+#ifdef __KERNEL__
+typedef unsigned long int pthread_t;
+#endif /*__KERNEL__ */
+
+
+#ifndef PXLOG_BINARY
+#define PXLOG_BINARY	1
+#endif /* PXLOG_BINARY */
+
+#ifndef LOG_KERN
+#define LOG_KERN	0
+#endif /* LOG_KERN */
+
+#ifndef LOG_DEBUG
+#define LOG_DEBUG	7
+#endif /* LOG_DEBUG */
+
+#define LOGFILE_MAGIC   0xbeefface
+#define LOGREC_MAGIC    0xfeefface
+
+#define LKST_ARCH_NAME_LEN 65
+
+/* Logfile Header for evlog compatibility. */
+typedef struct log_header {
+	uint		log_magic;	/* Magic number indicating log file */
+	long		log_version;	/* Event logging version */
+	posix_log_recid_t last_recId;	/* Last recid in log: used by evlogd */
+	off_t		reserved1;
+	uint		log_generation;	/* Changes during log maintenance */
+} log_header_t;
+
+struct lkst_log_buffer {
+	size_t read_size;		/* size of event records to read */
+	lkst_buffer_id id;		/* event buffer ID */
+	size_t result_read_size;	/* size of read event records */
+	struct timeval xtime;		/* xtime */
+	lkst_tsc_t tsc;			/* machine cycle */ 
+					/* These two will be used to calculate 
+					 * time of events in real time. */
+	lkst_cpu_freq_t	cpu_freq;	/* cpu clockspeed in kHz */ 
+	struct lkst_log_record *buffer;
+			/* address of a buffer to store event records */
+
+	int endian_big;			/* byte order, 0 if little endian */
+	int buf_ver;			/* LKST buffer version */
+	char arch[LKST_ARCH_NAME_LEN];	/* Architecture name */
+};
+
+struct posix_log_entry {
+	unsigned int log_magic;
+	posix_log_recid_t log_recid;	/* ID of the event record */
+	size_t log_size;	/* size of the event record variable data */
+	int log_format;		/* format of variable data */
+	int log_event_type;	/* event identification code */
+	posix_log_facility_t log_facility;	/* event facility code */
+	posix_log_severity_t log_severity;	/* event severity code */
+	uid_t log_uid;	/* effective user ID associated with the event */
+	gid_t log_gid;	/* effective group ID associated with the event */
+	pid_t log_pid;	/* process ID associated with event */
+	pid_t log_pgrp;	/* process group associated with event */
+	struct timespec log_time;	/* event time stamp */
+	unsigned int log_flags;		/* bitmap of event flag */
+	pthread_t log_thread;		/* thread ID associated with event */
+	posix_log_procid_t log_processor; /* processor ID associated with event */
+};
+
+struct lkst_log_record {
+	struct posix_log_entry posix;	/* log form specified by POSIX */
+	lkst_arg_t log_arg1;
+			/* 1st argument acquired at a trace point */
+	lkst_arg_t log_arg2;
+			/* 2nd argument acquired at a trace point */
+	lkst_arg_t log_arg3;
+			/* 3rd argument acquired at a trace point */
+	lkst_arg_t log_arg4;
+			/* 4th argument acquired at a trace point */
+};
+
+struct lkst_buffer_param {
+	lkst_buffer_id id;	/* event buffer ID */
+	int cpu;		/* cpu number */
+	size_t size;		/* size of event buffer */
+	size_t result_size;	/* result size of event buffer */
+};
+
+struct lkst_buffer_listent {
+	size_t size;			/* buffer size */
+	size_t readp;
+	size_t writep;
+	unsigned int wrap_flag;
+	unsigned int current_flag;
+	lkst_buffer_id id, prev, next;	/* buffer ID of own/prev/next buffer */
+	int cpu;			/* cpu number of the buffer */
+};
+
+#if DEBUG
+struct lkst_buffer_seekparam {
+	int offset;		/* offset of a read pointer */
+	lkst_buffer_id id;	/* event buffer ID */
+	size_t result_readp;	/* changed read pointer */
+};
+#endif /* DEBUG */
+
+struct lkst_buffer_listparam {
+	size_t listent_size;		/* size of the listent */
+	struct lkst_buffer_listent *listent;
+				/* area to store the list of event buffers */
+};
+
+struct lkst_buffer_ringparam {
+	int cpu;	/* cpu number */
+	int ring;	/* ring flag */
+};
+
+struct lkst_buffer_srmodparam {
+	int cpu;	/* cpu number */
+	int mode;	/* read mode */
+	struct timeval xtime;		/* xtime */
+	lkst_tsc_t tsc;			/* machine cycle */ 
+					/* These two will be used to calculate 
+					 * time of events in real time. */
+	lkst_cpu_freq_t	cpu_freq;	/* cpu clockspeed in kHz */ 
+	int endian_big;			/* byte order, 0 if little endian */
+	int buf_ver;			/* LKST buffer version */
+	char arch[LKST_ARCH_NAME_LEN];	/* Architecture name */
+};
+
+int lkst_buffer_read(struct lkst_log_buffer *lbuffer);
+
+int lkst_buffer_create(struct lkst_buffer_param *buffer_param);
+
+int lkst_buffer_shift(int cpu);
+
+int lkst_buffer_delete(lkst_buffer_id id);
+
+#if DEBUG
+int lkst_buffer_seek(struct lkst_buffer_seekparam *bs);
+#endif /* DEBUG */
+
+int lkst_buffer_list(struct lkst_buffer_listparam *lp);
+
+int lkst_buffer_ring(struct lkst_buffer_ringparam *rp);
+
+int lkst_buffer_setrmod(struct lkst_buffer_srmodparam *sp);
+
+#define LKST_BUFFER_LISTENT_SIZE(n)					\
+	     (sizeof(struct lkst_buffer_listent) * (n))
+
+#define LKST_BUFFER_SIZE_LOCAL2EXT(size) 				\
+		((size)*sizeof(struct lkst_log_record)/LKST_SIZEOF_LKST_EVENT_RECORD)
+
+#endif				/* _LINUX_LKST_BUFFER_H */
+
+/* END */
diff -Naur kernel.orig/linux24/include/linux/lkst_events.h kernel/linux24/include/linux/lkst_events.h
--- kernel.orig/linux24/include/linux/lkst_events.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/linux/lkst_events.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,840 @@
+/* $Id: lkst_events.h,v 1.8 2002/06/28 11:27:56 indoh Exp $ */
+/* linux/include/linux/lkst_events.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by K.SERIZAWA <serizawa@sdl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+/*******************************************************
+ *
+ *  This file may be included twice or more!
+ *
+ *******************************************************/
+
+	/* The list of mnemonics:
+		If LKST_ETYPE_MNEMONICS is defined,
+ 		the list of LKST_ETYPE_DEF() will become a definition of 
+ 		lkst_event_type_mnemonics, 
+		that is an array of mnemonics of event types.	*/
+#if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DEF_MNEMONICS)&&(!defined LKST_ETYPE_DEF_MNEMONICS_DEFINED))
+
+				/* remember to undef 
+				   LKST_ETYPE_DEF{,_ENUM*}		*/
+#define	LKST_ETYPE_DEF_TOCLEAN
+
+				/* each element of the array is a pair of 
+				   mnemonic and value of event type.	*/
+#define LKST_ETYPE_DEF(event_type, prio, hooktype, mnemonic, description, event_name, filter, arg_1, arg_2, arg_3, arg_4)         \
+        [(event_type)] = #mnemonic,
+
+				/* The header of the array. */
+#define LKST_ETYPE_DEF_ENUM_BEGIN       char *lkst_event_type_mnemonics[] = {
+
+				/* The tail of the enum. It must end with 
+				   LKST_ETYPE_MAX.                    	*/
+#define LKST_ETYPE_DEF_ENUM_END         [LKST_ETYPE_MAX] = "LKST_ETYPE_MAX" };
+
+				/* Stopper of multi definition. */
+#define LKST_ETYPE_DEF_MNEMONICS_DEFINED
+
+#endif /* if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DEF_MNEMONICS)&&(!defined LKST_ETYPE_DEF_MNEMONICS_DEFINED)) */
+
+/*******************************************************/
+
+
+	/* The list of descriptions:
+		If LKST_ETYPE_DEF_DESCRIPTIONS is defined,
+ 		the list of LKST_ETYPE_DEF() will become a definition of 
+ 		lkst_event_type_descriptions, 
+		that is an array of descriptions of event types.	*/
+#if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DEF_DESCRIPTIONS)&&(!defined LKST_ETYPE_DEF_DESCRIPTIONS_DEFINED))
+
+				/* remember to undef 
+				   LKST_ETYPE_DEF{,_ENUM*}		*/
+#define	LKST_ETYPE_DEF_TOCLEAN
+
+				/* each element of the array is a pair of 
+				   description and value of event type.	*/
+#define LKST_ETYPE_DEF(event_type, prio, hooktype, mnemonic, description, event_name, filter, arg_1, arg_2, arg_3, arg_4)         \
+        [(event_type)] = #description,
+
+				/* The header of the array. */
+#define LKST_ETYPE_DEF_ENUM_BEGIN       char *lkst_event_type_descriptions[] = {
+
+				/* The tail of the enum. It must end with 
+				   LKST_ETYPE_MAX.                    	*/
+#define LKST_ETYPE_DEF_ENUM_END         [LKST_ETYPE_MAX] = "LKST_ETYPE_MAX" };
+
+				/* Stopper of multi definition. */
+#define LKST_ETYPE_DEF_DESCRIPTIONS_DEFINED
+
+#endif /* if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DEF_DESCRIPTIONS)&&(!defined LKST_ETYPE_DEF_DESCRIPTIONS_DEFINED)) */
+
+/*******************************************************/
+
+
+	/* The list of event data */
+#if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DEF_DATATABLE)&&(!defined LKST_ETYPE_DEF_DATATABLE_DEFINED))
+
+				/* remember to undef 
+				   LKST_ETYPE_DEF{,_ENUM*}		*/
+#define	LKST_ETYPE_DEF_TOCLEAN
+
+				/* each element of the array is a pair of 
+				   description and value of event type.	*/
+
+#define LKST_ETYPE_DEF(event_type, prio, hooktype, mnemonic, description, event_name, filter, arg_1, arg_2, arg_3, arg_4)         \
+        [(event_type)] = { event_name, filter, { arg_1, arg_2, arg_3, arg_4 }, },
+
+				/* The header of the array. */
+#define LKST_ETYPE_DEF_ENUM_BEGIN       	struct LKST_list {                      \
+                                                        char*	LKST_event_name;    \
+                                                        int	LKST_filter;            \
+                                                        char*	LKST_inf_args[4];   \
+                                                        }LKST_event_data[]={
+
+				/* The tail of the enum. It must end with 
+				   LKST_ETYPE_MAX.                    	*/
+#define LKST_ETYPE_DEF_ENUM_END         [LKST_ETYPE_MAX] = "LKST_ETYPE_MAX" };
+
+				/* Stopper of multi definition. */
+#define LKST_ETYPE_DEF_DATATABLE_DEFINED
+
+#endif /* if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DEF_DESCRIPTIONS)&&(!defined LKST_ETYPE_DEF_DESCRIPTIONS_DEFINED)) */
+
+/*******************************************************/
+
+
+	/* The list of GKHI Declaration of hook header :
+		If LKST_ETYPE_DECLARE_HOOKHEADER is defined,
+ 		the list of LKST_ETYPE_DEF() will become a declaration of 
+ 		hook header and hook_rec_t data.	*/
+#if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DECLARE_HOOKHEADER)&&(!defined LKST_ETYPE_DECLARE_HOOKHEADER_DEFINED))
+
+				/* remember to undef 
+				   LKST_ETYPE_DEF{,_ENUM*}		*/
+#define	LKST_ETYPE_DEF_TOCLEAN
+
+				/* each element of the array is a pair of 
+				   description and value of event type.	*/
+
+#define LKST_ETYPE_DEF(event_type, prio, hooktype, mnemonic, description, event_name, filter, arg_1, arg_2, arg_3, arg_4) \
+        HOOK_DECL_##hooktype(LKST_ETYPE_##mnemonic);
+
+#define HOOK_DECL_NORMAL(etype) LKST_HOOK_DECLARE(etype)
+#define HOOK_DECL_INLINE(etype) LKST_HOOK_DECLARE_INLINE(etype)
+#define HOOK_DECL_MODULE(etype)
+#define HOOK_DECL_UNDEF(etype)
+
+#define LKST_ETYPE_DEF_ENUM_BEGIN
+#define LKST_ETYPE_DEF_ENUM_END
+
+				/* Stopper of multi definition. */
+#define LKST_ETYPE_DECLARE_HOOKHEADER_DEFINED
+
+#endif /* if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_DECLARE_HOOKHEADER)&&(!defined LKST_ETYPE_DECLARE_HOOKHEADER_DEFINED)) */
+
+/*******************************************************/
+
+
+	/* The list of GKHI Initialization of hook header :
+		If LKST_ETYPE_INIT_HOOK is defined,
+ 		the list of LKST_ETYPE_DEF() will become a initialization of 
+ 		hook.	*/
+#if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_INIT_HOOK)&&(!defined LKST_ETYPE_INIT_HOOK_DEFINED))
+
+				/* remember to undef 
+				   LKST_ETYPE_DEF{,_ENUM*}		*/
+#define	LKST_ETYPE_DEF_TOCLEAN
+
+				/* each element of the array is a pair of 
+				   description and value of event type.	*/
+
+#define LKST_ETYPE_DEF(event_type, prio, hooktype, mnemonic, description, event_name, filter, arg_1, arg_2, arg_3, arg_4) \
+        HOOK_INIT_##hooktype(LKST_ETYPE_##mnemonic)
+
+#define HOOK_INIT_NORMAL(etype) LKST_HOOK_INIT(etype, ret); \
+                                retall += ret;
+#define HOOK_INIT_INLINE(etype) LKST_HOOK_INIT(etype, ret); \
+                                retall += ret;
+#define HOOK_INIT_MODULE(etype)
+#define HOOK_INIT_UNDEF(etype)
+
+
+#define LKST_ETYPE_DEF_ENUM_BEGIN
+#define LKST_ETYPE_DEF_ENUM_END
+
+				/* Stopper of multi definition. */
+#define LKST_ETYPE_INIT_HOOK_DEFINED
+
+#endif /* if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_INIT_HOOK)&&(!defined LKST_ETYPE_INIT_HOOK_DEFINED)) */
+
+/*******************************************************/
+
+
+	/* The list of GKHI Cleanup of hook header :
+		If LKST_ETYPE_TERMINATE_HOOK is defined,
+ 		the list of LKST_ETYPE_DEF() will become a cleanup of 
+ 		hook.	*/
+#if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_TERMINATE_HOOK)&&(!defined LKST_ETYPE_TERMINATE_HOOK_DEFINED))
+
+				/* remember to undef 
+				   LKST_ETYPE_DEF{,_ENUM*}		*/
+#define	LKST_ETYPE_DEF_TOCLEAN
+
+				/* each element of the array is a pair of 
+				   description and value of event type.	*/
+
+#define LKST_ETYPE_DEF(event_type, prio, hooktype, mnemonic, description, event_name, filter, arg_1, arg_2, arg_3, arg_4) \
+        HOOK_TERMINATE_##hooktype(LKST_ETYPE_##mnemonic)
+
+#define HOOK_TERMINATE_NORMAL(etype) LKST_HOOK_TERMINATE(etype, ret); \
+                                     retall += ret;
+#define HOOK_TERMINATE_INLINE(etype) LKST_HOOK_TERMINATE(etype, ret); \
+                                     retall += ret;
+#define HOOK_TERMINATE_MODULE(etype)
+#define HOOK_TERMINATE_UNDEF(etype)
+
+#define LKST_ETYPE_DEF_ENUM_BEGIN
+#define LKST_ETYPE_DEF_ENUM_END
+
+				/* Stopper of multi definition. */
+#define LKST_ETYPE_TERMINATE_HOOK_DEFINED
+
+#endif /* if	(!(defined LKST_ETYPE_DEF)&&(defined LKST_ETYPE_TERMINATE_HOOK)&&(!defined LKST_ETYPE_TERMINATE_HOOK_DEFINED)) */
+
+/*******************************************************/
+
+
+	/* The enumerate of event types:
+		By default,
+ 		the list of LKST_ETYPE_DEF() will become a definition of 
+ 		lkst_event_type_descriptions, 
+		that is an array of descriptions of event types.	*/
+#if	(!(defined LKST_ETYPE_DEF))
+				/* The list of LKST_ETYPE_DEF()
+				   will be a definition of an enum. of
+				   event types.				*/
+
+				/* remember to undef 
+				   LKST_ETYPE_DEF{,_ENUM*}.		*/
+#define	LKST_ETYPE_DEF_TOCLEAN
+
+				/* each element of the enum. is a pair of 
+				   a name and value of event type.   	*/
+
+#define	LKST_ETYPE_DEF(event_type, prio, hooktype, mnemonic, description, event_name, filter, arg_1, arg_2, arg_3, arg_4)		\
+	LKST_ETYPE_##mnemonic =	(event_type),
+
+				/* The header of the enum. */
+#define LKST_ETYPE_DEF_ENUM_BEGIN					\
+	typedef enum {
+
+				/* The tail of the enum. It must end with 
+				   LKST_ETYPE_MAX.                    	*/
+#define LKST_ETYPE_DEF_ENUM_END						\
+		LKST_ETYPE_MAX = 0xFFF+0				\
+	} lkst_event_type;
+
+				/* remenber not redefine LKST_ETYPE_MAX. */
+#define	LKST_ETYPE_MAX_IS_ENUM
+
+#endif /* if	(!(defined LKST_ETYPE_DEF)) */
+
+
+/*******************************************************/
+
+    /* header */
+LKST_ETYPE_DEF_ENUM_BEGIN
+
+    /* Body of definitions of event types */
+    /* Syntax:
+        LKST_ETYPE_DEF(
+            VALUE_OF_THE_EVENT_TYPE:(0x001..0xffe),
+            PRIORITY_OF_THE_EVENT_TYPE:(0x00..0xff),
+            TYPE OF GKHI HOOK HEADER,
+            MNEMONIC_OF_THE_EVENT_TYPE,
+            DESCRIPTION_OF_THE_EVENT_TYPE,
+            EVENT_NAME_STRING,
+            DISPLAY_FILTER,
+            EVENT_ARG1,
+            EVENT_ARG2,
+            EVENT_ARG3,
+            EVENT_ARG4 )                  */
+
+LKST_ETYPE_DEF(0x001, 0x00, NORMAL, PROCESS_CONTEXTSWITCH, PROCESS_CONTEXTSWITCH,   \
+        // 0x001 event
+        "context_switch",                                                           \
+         0,                                                                         \
+        "pointer to task_struct(prev)",                                             \
+        "pointer to task_struct(next)",                                             \
+        "process state/process count",                                              \
+         NULL)
+LKST_ETYPE_DEF(0x002, 0x00, INLINE, PROCESS_WAKEUP, PROCESS_WAKEUP,                 \
+        // 0x002 event
+        "process_wakeup",                                                           \
+         0,                                                                         \
+        "pointer to wakeup-process(p)",                                             \
+        "synchronous",                                                              \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x003, 0x00, NORMAL, PROCESS_SIGSEND, PROCESS_SIGSEND,               \
+        // 0x003 event
+        "process_sigsend",                                                          \
+         0,                                                                         \
+        "signal number(sig)",                                                       \
+        "pointer to process to which signal is sent",                               \
+        "pointer to info structure(info)",                                          \
+         NULL)
+LKST_ETYPE_DEF(0x004, 0x00, NORMAL, PROCESS_LTHREADGEN, PROCESS_LTHREADGEN,         \
+        // 0x004 event
+        "kernel_thread",                                                            \
+         0,                                                                         \
+        "pointer to kernel thread(fn)",                                             \
+        "argument of kernel thread(arg)",                                           \
+        "flag",                                                                     \
+         NULL)
+
+LKST_ETYPE_DEF(0x010, 0x01, NORMAL, INT_HARDWARE_ENTRY, INT_HARDWARE_ENTRY,         \
+        //0x010 event
+        "interrupt_hardware_entry",                                                 \
+         0,                                                                         \
+        "IRQ number(irq)",                                                          \
+        "interrupt status(status)",                                                 \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x012, 0x01, NORMAL, INT_TASKLETHI_ENTRY, INT_TASKLETHI_ENTRY,       \
+        //0x012 event
+        "interrupt_tasklethi_entry",                                                \
+         0,                                                                         \
+        "action address(t->func)",                                                  \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x014, 0x01, NORMAL, INT_TASKLET_ENTRY, INT_TASKLET_ENTRY,           \
+        //0x014 event
+        "interrupt_tasklet_entry",                                                  \
+         0,                                                                         \
+        "action address(t->func)",                                                  \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x016, 0x01, NORMAL, INT_BH_ENTRY, INT_BH_ENTRY,                     \
+        //0x016 event
+        "interrupt_bh_entry",                                                       \
+         0,                                                                         \
+        "interrupt type(nr)",                                                       \
+        "action address(bh_base)",                                                  \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0x020, 0x02, INLINE, EXCEPTION_ENTRY, EXCEPTION_ENTRY,               \
+        //0x020 event
+        "exception_entry",                                                          \
+         0,                                                                         \
+        "exception-handler address(edi)",                                           \
+        "error code(esi)",                                                          \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x021, 0x02, INLINE, EXCEPTION_EXIT, EXCEPTION_EXIT,                 \
+        //0x021 event
+        "exception_exit",                                                           \
+         0,                                                                         \
+        "exception-handler address(edi)",                                           \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0x030, 0x03, NORMAL, SYSCALL_ENTRY, SYSCALL_ENTRY,                   \
+        //0x030 event
+        "system_call_entry",                                                        \
+         0,                                                                         \
+        "call number",                                                              \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x031, 0x03, NORMAL, SYSCALL_EXIT, SYSCALL_EXIT,                     \
+        //0x031 event
+        "system_call_exit",                                                         \
+         0,                                                                         \
+        "call number",                                                              \
+        "return value(errno)",                                                      \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0x040, 0x04, NORMAL, FS_DEVRW, FS_DEVRW,                             \
+        //0x040 event
+        "fs_devrw",                                                                 \
+         0,                                                                         \
+        "buffer(bh)",                                                               \
+        "READ/WRITE(rw)",                                                           \
+        "the number of block transfered(nr)",                                       \
+         NULL)
+LKST_ETYPE_DEF(0x041, 0x04, NORMAL, FS_DEVEND, FS_DEVEND,                           \
+        //0x041 event
+        "fs_devend",                                                                \
+         0,                                                                         \
+        "buffer(bf)",                                                               \
+        "uptodate",                                                                 \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x042, 0x04, NORMAL, FS_BUFBUSY, FS_BUFBUSY,                         \
+        //0x042 event
+        "fs_devwait",                                                               \
+         0,                                                                         \
+        "buffer(bh)",                                                               \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0x050, 0x05, INLINE, MEM_SWAPOUT, MEM_SWAPOUT,                       \
+        //0x050 event
+        "mem_swapout",                                                              \
+         0,                                                                         \
+        "pointer to page swapped-out",                                              \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x051, 0x05, NORMAL, MEM_SWAPIN, MEM_SWAPIN,                         \
+        //0x051 event
+        "mem_swapin",                                                               \
+         0,                                                                         \
+        "pointer to page swapped-in",                                               \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x052, 0x05, NORMAL, MEM_DO_NOPAGE, MEM_DO_NOPAGE,                   \
+        //0x052 event
+        "mem_do_nopage",                                                            \
+         0,                                                                         \
+        "pointer to page allocated",                                                \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x053, 0x05, NORMAL, MEM_DO_WPPAGE, MEM_DO_WPPAGE,                   \
+        //0x053 event
+        "mem_do_wppage",                                                            \
+         0,                                                                         \
+        "pointer to page",                                                          \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x054, 0x05, NORMAL, MEM_WAIT_PAGE, MEM_WAIT_PAGE,                   \
+        //0x054 event
+        "mem_wait_page",                                                            \
+         0,                                                                         \
+        "pointer to page",                                                          \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x055, 0x05, NORMAL, MEM_GET_FREEPAGE, MEM_GET_FREEPAGE,             \
+        //0x055 event
+        "mem_get_freepage",                                                         \
+         0,                                                                         \
+        "pointer to page",                                                          \
+        "type of page(gfp_mask)",                                                   \
+        "the number of page(order)",                                                \
+        "call address")
+LKST_ETYPE_DEF(0x056, 0x05, NORMAL, MEM_GET_ZEROPAGE, MEM_GET_ZEROPAGE,             \
+        //0x056 event
+        "mem_get_zeropage",                                                         \
+         0,                                                                         \
+        "pointer to page",                                                          \
+        "type of page(gfp_mask)",                                                   \
+        "call address",                                                             \
+         NULL)
+LKST_ETYPE_DEF(0x057, 0x05, NORMAL, MEM_FREEPAGE, MEM_FREEPAGE,                     \
+        //0x057 event
+        "mem_freepage",                                                             \
+         0,                                                                         \
+        "pointer to page",                                                          \
+        "the number of page(order)",                                                \
+        "call address",                                                             \
+         NULL)
+LKST_ETYPE_DEF(0x058, 0x05, INLINE, MEM_VMALLOC, MEM_VMALLOC,                       \
+        //0x058 event
+        "mem_vmalloc",                                                              \
+         0,                                                                         \
+        "address(addr)",                                                            \
+        "size",                                                                     \
+        "call address",                                                             \
+         NULL)
+LKST_ETYPE_DEF(0x059, 0x05, NORMAL, MEM_VFREE, MEM_VFREE,                           \
+        //0x059 event
+        "mem_vfree",                                                                \
+         0,                                                                         \
+        "address(addr)",                                                            \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x05a, 0x05, NORMAL, MEM_CACHE_CREATE, MEM_CACHE_CREATE,             \
+        //0x05a event
+        "mem_cache_create",                                                         \
+         0,                                                                         \
+        "name",                                                                     \
+        "size",                                                                     \
+        "cachep",                                                                   \
+         NULL)
+LKST_ETYPE_DEF(0x05b, 0x05, NORMAL, MEM_CACHE_ALLOC, MEM_CACHE_ALLOC,               \
+        //0x05b event
+        "mem_cache_alloc",                                                          \
+         0,                                                                         \
+        "cachep",                                                                   \
+        "flags",                                                                    \
+        "objp",                                                                     \
+        "call address")
+LKST_ETYPE_DEF(0x05c, 0x05, NORMAL, MEM_MALLOC, MEM_MALLOC,                         \
+        //0x05c event
+        "mem_malloc",                                                               \
+         0,                                                                         \
+        "size",                                                                     \
+        "flags",                                                                    \
+        "objp",                                                                     \
+        "call address")
+LKST_ETYPE_DEF(0x05d, 0x05, NORMAL, MEM_CACHE_FREE, MEM_CACHE_FREE,                 \
+        //0x05d event
+        "mem_cache_free",                                                           \
+         0,                                                                         \
+        "cachep",                                                                   \
+        "objp",                                                                     \
+        "call address",                                                             \
+         NULL)
+LKST_ETYPE_DEF(0x05e, 0x05, NORMAL, MEM_FREE, MEM_FREE,                             \
+        //0x05e event
+        "mem_free",                                                                 \
+         0,                                                                         \
+        "objp",                                                                     \
+        "call address",                                                             \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0x060, 0x06, NORMAL, NET_PKTSEND, NET_PKTSEND,                       \
+        //0x060 event
+        "net_pktsend",                                                              \
+         0,                                                                         \
+        "skb",                                                                      \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x061, 0x06, NORMAL, NET_PKTSENDI, NET_PKTSENDI,                     \
+        //0x061 event
+        "net_pktsendi",                                                             \
+         0,                                                                         \
+        "h",                                                                        \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x062, 0x06, NORMAL, NET_PKTRECV, NET_PKTRECV,                       \
+        //0x062 event
+        "net_pktrecv",                                                              \
+         0,                                                                         \
+        "skb",                                                                      \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x063, 0x06, NORMAL, NET_PKTRECVI, NET_PKTRECVI,                     \
+        //0x063 event
+        "net_pktrecvi",                                                             \
+         0,                                                                         \
+        "h",                                                                        \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x064, 0x06, NORMAL, NET_SOCKETIF, NET_SOCKETIF,                     \
+        //0x064 event
+        "net_socketif",                                                             \
+         0,                                                                         \
+        "call",                                                                     \
+        "args",                                                                     \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0x070, 0x07, NORMAL, SYSV_IPC, SYSV_IPC,                             \
+        //0x070 event
+        "sysv_ipc",                                                                 \
+         0,                                                                         \
+        "call/first",                                                               \
+        "second/third",                                                             \
+        "*ptr",                                                                     \
+         NULL)
+
+    /* Events concerned with spinlocks should have event_type as 0x08x. */
+LKST_ETYPE_DEF(0x080, 0x08, INLINE, LK_SPINLOCK, LK_SPINLOCK,                       \
+        //0x080 event
+        "spin_lock",                                                                \
+         0,                                                                         \
+        "call address",                                                             \
+        "lock",                                                                     \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x081, 0x08, INLINE, LK_SPINTRYLOCK, LK_SPINTRYLOCK,                 \
+        //0x081 event
+        "spin_trylock",                                                             \
+         0,                                                                         \
+        "call address",                                                             \
+        "lock",                                                                     \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x082, 0x08, INLINE, LK_SPINUNLOCK, LK_SPINUNLOCK,                   \
+        //0x082 event
+        "spin_unlock",                                                              \
+         0,                                                                         \
+        "call address",                                                             \
+        "lock",                                                                     \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x083, 0x08, INLINE, LK_WRLOCK, LK_WRLOCK,                           \
+        //0x083 event
+        "write_lock",                                                               \
+         0,                                                                         \
+        "call address",                                                             \
+        "rwlock",                                                                   \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x084, 0x08, INLINE, LK_WRTRYLOCK, LK_WRTRYLOCK,                     \
+        //0x084 event
+        "write_trylock",                                                            \
+         0,                                                                         \
+        "call address",                                                             \
+        "rwlock",                                                                   \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x085, 0x08, INLINE, LK_WRUNLOCK, LK_WRUNLOCK,                       \
+        //0x085 event
+        "write_unlock",                                                             \
+         0,                                                                         \
+        "call address",                                                             \
+        "rwlock",                                                                   \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x086, 0x08, INLINE, LK_RDLOCK, LK_RDLOCK,                           \
+        //0x086 event
+        "read_lock",                                                                \
+         0,                                                                         \
+        "call address",                                                             \
+        "rwlock",                                                                   \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x087, 0x08, INLINE, LK_RDUNLOCK, LK_RDUNLOCK,                       \
+        //0x087 event
+        "read_unlock",                                                              \
+         0,                                                                         \
+        "call address",                                                             \
+        "rwlock",                                                                   \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x088, 0x08, UNDEF,  LK_RESV88, LK_RESV88, NULL, 0, NULL, NULL, NULL, NULL)
+LKST_ETYPE_DEF(0x089, 0x08, UNDEF,  LK_RESV89, LK_RESV89, NULL, 0, NULL, NULL, NULL, NULL)
+LKST_ETYPE_DEF(0x08a, 0x08, UNDEF,  LK_RESV8a, LK_RESV8a, NULL, 0, NULL, NULL, NULL, NULL)
+LKST_ETYPE_DEF(0x08b, 0x08, UNDEF,  LK_RESV8b, LK_RESV8b, NULL, 0, NULL, NULL, NULL, NULL)
+LKST_ETYPE_DEF(0x08c, 0x08, UNDEF,  LK_RESV8c, LK_RESV8c, NULL, 0, NULL, NULL, NULL, NULL)
+LKST_ETYPE_DEF(0x08d, 0x08, UNDEF,  LK_RESV8d, LK_RESV8d, NULL, 0, NULL, NULL, NULL, NULL)
+LKST_ETYPE_DEF(0x08e, 0x08, UNDEF,  LK_RESV8e, LK_RESV8e, NULL, 0, NULL, NULL, NULL, NULL)
+LKST_ETYPE_DEF(0x08f, 0x08, UNDEF,  LK_RESV8f, LK_RESV8f, NULL, 0, NULL, NULL, NULL, NULL)
+
+LKST_ETYPE_DEF(0x090, 0x09, INLINE, O_PORTIN, O_PORTIN,                             \
+        //0x090 event
+        "portin",                                                                   \
+         0,                                                                         \
+        "port address/bite-width",                                                  \
+        "value",                                                                    \
+        "call address",                                                             \
+         NULL)
+LKST_ETYPE_DEF(0x091, 0x09, INLINE, O_PORTOUT, O_PORTOUT,                           \
+        //0x091 event
+        "portout",                                                                  \
+         0,                                                                         \
+        "port address/bite-width",                                                  \
+        "value",                                                                    \
+        "call address",                                                             \
+         NULL)
+LKST_ETYPE_DEF(0x092, 0x09, NORMAL, O_PANIC, O_PANIC,                               \
+        //0x092 event
+        "panic",                                                                    \
+         0,                                                                         \
+        "address of argument",                                                      \
+        "call address",                                                             \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x093, 0x09, NORMAL, O_PRINTK, O_PRINTK,                             \
+        //0x093 event
+        "printk",                                                                   \
+         0,                                                                         \
+        "address of argument",                                                      \
+        "call address",                                                             \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0x0a0, 0x0a, INLINE, TIMER_RUN, TIMER_RUN,                           \
+        //0x0a0 event
+        "timer_run",                                                                \
+         0,                                                                         \
+        "function address(fn)",                                                     \
+        "parameter(data)",                                                          \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0x0a1, 0x0a, NORMAL, TIMER_ADD, TIMER_ADD,                           \
+        //0x0a1 event
+        "timer_add",                                                                \
+         0,                                                                         \
+        "timer",                                                                    \
+        "timer->expires",                                                           \
+        "timer->function",                                                          \
+        "timer->data")
+LKST_ETYPE_DEF(0x0a2, 0x0a, NORMAL, TIMER_MOD, TIMER_MOD,                           \
+        //0x0a2 event
+        "timer_mod",                                                                \
+         0,                                                                         \
+        "timer",                                                                    \
+        "timer->expires",                                                           \
+        "timer->function",                                                          \
+        "timer->data")
+LKST_ETYPE_DEF(0x0a3, 0x0a, NORMAL, TIMER_DEL, TIMER_DEL,                           \
+        //0x0a3 event
+        "timer_del",                                                                \
+         0,                                                                         \
+        "timer",                                                                    \
+        "timer->expires",                                                           \
+        "timer->function",                                                          \
+        "timer->data")
+#ifdef CONFIG_SMP
+LKST_ETYPE_DEF(0x0a4, 0x0a, NORMAL, TIMER_DEL_SYNC, TIMER_DEL_SYNC,                 \
+        //0x0a4 event
+        "timer_del_sync",                                                           \
+         0,                                                                         \
+        "timer",                                                                    \
+        "timer->expires",                                                           \
+        "timer->function",                                                          \
+        "timer->data")
+#endif /* CONFIG_SMP */
+
+LKST_ETYPE_DEF(0xF00, 0xF0, INLINE, LKST_INIT, LKST_INIT,                           \
+        //0xf00 event
+        "lkst_init",                                                                \
+         0,                                                                         \
+        "data",                                                                     \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0xF08, 0xF0, INLINE, LKST_MSET_XCHG, LKST_MSET_XCHG,                 \
+        //0xf08 event
+        "lkst_mset_xchg",                                                           \
+         0,                                                                         \
+        "old_id/new_id",                                                            \
+        "old_maskset",                                                              \
+        "new_maskset",                                                              \
+         NULL)
+
+LKST_ETYPE_DEF(0xF10, 0xF1, INLINE, LKST_BUFF_SHIFT, LKST_BUFF_SHIFT,               \
+        //0xf10 event
+        "lkst_buff_shift",                                                          \
+         0,                                                                         \
+        "buffer",                                                                   \
+        "next_buffer",                                                              \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0xF11, 0xF1, INLINE, LKST_BUFF_OVFLOW, LKST_BUFF_OVFLOW,             \
+        //0xf11 event
+        "lkst_buff_ovflow",                                                         \
+         0,                                                                         \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0xF12, 0xF1, UNDEF,  LKST_BUFF_HIGH, LKST_BUFF_HIGH,                 \
+        //0xf12 event
+        "lkst_buff_high",                                                           \
+         0,                                                                         \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0xF18, 0xF1, UNDEF,  LKST_SYNC_TIME, LKST_SYNC_TIME,                 \
+        //0xf18 event
+        "lkst_sync_time",                                                           \
+         0,                                                                         \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+LKST_ETYPE_DEF(0xF19, 0xF1, INLINE, LKST_SYNC_UID, LKST_SYNC_UID,                   \
+        //0xf19 event
+        "lkst_sync_uid",                                                            \
+         0,                                                                         \
+        "ruid",                                                                     \
+         NULL,                                                                      \
+        "currnet",                                                                  \
+         NULL)
+LKST_ETYPE_DEF(0xF1A, 0xF1, INLINE, LKST_SYNC_GID, LKST_SYNC_GID,                   \
+        //0xf1a event
+        "lkst_sync_gid",                                                            \
+         0,                                                                         \
+        "rgid",                                                                     \
+         NULL,                                                                      \
+        "currnet",                                                                  \
+         NULL)
+LKST_ETYPE_DEF(0xF1B, 0xF1, INLINE, LKST_SYNC_PGID, LKST_SYNC_PGID,                 \
+        //0xf1b event
+        "lkst_sync_pgid",                                                           \
+         0,                                                                         \
+        "pid",                                                                      \
+        "pgrp",                                                                     \
+        "pointer to task_struct",                                                   \
+        "leader")
+LKST_ETYPE_DEF(0xF1C, 0xF1, NORMAL, LKST_SYNC_TID, LKST_SYNC_TID,                   \
+        //0xf1c event
+        "lkst_sync_tid",                                                            \
+         0,                                                                         \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL,                                                                      \
+         NULL)
+
+LKST_ETYPE_DEF(0xFFC, 0xFF, UNDEF,  LKST_EXTEND, LKST_EXTEND, NULL, 0, NULL, NULL, NULL, NULL)	// TODO: Tantative code
+LKST_ETYPE_DEF(0xFFD, 0xFF, UNDEF,  LKST_EXTENDE, LKST_EXTENDE, NULL, 0, NULL, NULL, NULL, NULL)	// TODO: Tantative code
+LKST_ETYPE_DEF(0xFFE, 0xFF, UNDEF,  LKST_OVWRTN_REC, LKST_OVWRTN_REC,               \
+        //0xffe event
+        "overwritten_record",                                                       \
+         0,                                                                         \
+        "old arg1",                                                                 \
+        "old arg2",                                                                 \
+        "old arg3",                                                                 \
+        "old event_type")
+
+
+#if	((!defined(LKST_ETYPE_MAX_IS_ENUM))&&(!defined(LKST_ETYPE_MAX)))
+        /* By default, LKST_ETYPE_MAX is
+           defined as an element of the enum.
+           Otherwise here LKST_ETYPE_MAX is 
+           defined as a MACRO.               */
+#define LKST_ETYPE_MAX  (0xFFF+0)
+
+#endif /* if ((!defined(LKST_ETYPE_MAX_IS_ENUM))&&(!defined(LKST_ETYPE_MAX))) */
+
+#ifndef	LKST_ETYPE_VOID
+#define LKST_ETYPE_VOID  (LKST_ETYPE_MAX+1)
+#endif /* ifndef LKST_ETYPE_VOID */
+
+    /* tail */
+LKST_ETYPE_DEF_ENUM_END
+
+        /* By default, undef LKST_ETYPE_DEF* 
+           for the next inclusion of this file. */
+#ifdef  LKST_ETYPE_DEF_TOCLEAN
+
+#undef  LKST_ETYPE_DEF
+#undef  LKST_ETYPE_DEF_ENUM_BEGIN
+#undef  LKST_ETYPE_DEF_ENUM_END
+#undef  LKST_ETYPE_DEF_TOCLEAN
+
+#endif /* ifdef LKST_ETYPE_DEF_TOCLEAN */
+
+/* END */
diff -Naur kernel.orig/linux24/include/linux/lkst_evhandler.h kernel/linux24/include/linux/lkst_evhandler.h
--- kernel.orig/linux24/include/linux/lkst_evhandler.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/linux/lkst_evhandler.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,57 @@
+/* $Id: lkst_evhandler.h,v 1.5 2002/03/27 17:36:26 serizawa Exp $ */
+/* linux/include/linux/lkst_evhandler.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by K.HATASAKI <keisukeh@crl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#ifndef _LINUX_LKST_EVHANDLER_H
+#define _LINUX_LKST_EVHANDLER_H
+
+#include<linux/lkst.h>
+
+#define LKST_EVHANDLER_NAME_LEN		256
+
+#define LKST_EVHANDLER_NAME_DMX			"DynamicMasksetXchg"
+#define LKST_EVHANDLER_NAME_DEFAULT		"DEFAULT"
+#define LKST_EVHANDLER_NAME_BUFFER_SHIFT	"BUFFER_SHIFT"
+#define LKST_EVHANDLER_NAME_BUFFER_SHIFT_DW	"BUFFER_SHIFT_AND_DAEMON_WAKEUP"
+#define LKST_EVHANDLER_NAME_EXCEPTION		"EXCEPTION"
+#define LKST_EVHANDLER_NAME_MASKSET_XCHG	"MASKSET_XCHG"
+
+typedef unsigned char lkst_evhandler_id;
+
+struct lkst_evhandler_ctrl_param {
+	lkst_evhandler_id id;	/* event handler ID */
+	void *buf;		/* a communication area for control-function */
+	size_t bufsize;		/* size of the communication area */
+	int ret;		/* return value from control-function */
+};
+
+struct lkst_evhandler_listent {
+	lkst_evhandler_id id;	/* event handler ID */
+	char name[LKST_EVHANDLER_NAME_LEN];
+					/* event handler name */
+};
+
+struct lkst_evhandler_listparam {
+	size_t listent_size;	/* size of the listent */
+	struct lkst_evhandler_listent *listent;
+				/* area to store the list of event handlers */
+};
+
+extern int lkst_evhandler_ctrl(struct lkst_evhandler_ctrl_param
+			       *evhandler_ctrl_param);
+
+extern int lkst_evhandler_list(struct lkst_evhandler_listparam *lp);
+
+#define LKST_EVHANDLER_LISTENT_SIZE(n)					\
+	     (sizeof(struct lkst_evhandler_listent) * (n))
+
+#endif				/* _LINUX_LKST_EVHANDLER_H */
diff -Naur kernel.orig/linux24/include/linux/lkst_maskset.h kernel/linux24/include/linux/lkst_maskset.h
--- kernel.orig/linux24/include/linux/lkst_maskset.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/linux/lkst_maskset.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,83 @@
+/* $Id: lkst_maskset.h,v 1.3 2002/03/25 19:05:34 serizawa Exp $ */
+/* linux/include/linux/lkst_maskset.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by T.Nakamura <tetsu@crl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#ifndef _LINUX_LKST_MASKSET_H
+#define _LINUX_LKST_MASKSET_H
+
+#include<linux/lkst.h>
+#include<linux/lkst_evhandler.h>
+
+#define LKST_MASKSET_NAME_LEN	256
+
+/* LKST_MASKSET_TBL_LEN_MAX means n of entries in a maskset. (cf. LKST_MASKSET_TBL_MAX */
+#define LKST_MASKSET_TABLE_LEN_MAX	((LKST_ETYPE_MAX)+1)
+
+#define LKST_MASKSET_NAME_RALL		"RALL"
+#define LKST_MASKSET_NAME_RNOTHING	"RNOTHING"
+#define LKST_MASKSET_NAME_RDEFAULT	"RDEFAULT"
+
+typedef int lkst_maskset_table_len;
+
+struct lkst_maskset_entry {
+	int event_type;			/* corresponding type of evnet */
+	lkst_evhandler_id id;	/* event handler ID */
+};
+
+struct lkst_maskset_body {
+	char name[LKST_MASKSET_NAME_LEN];	/* maskset name */
+	lkst_maskset_table_len len;	/* total number of maskset entries */
+	struct lkst_maskset_entry entry[LKST_MASKSET_TABLE_LEN_MAX];
+					/* maskset entry */
+};
+
+struct lkst_maskset_param {
+	lkst_maskset_id id;	/* maskset ID */
+	size_t maskset_size;	/* maskset size */
+	struct lkst_maskset_body *maskset;
+				/* address of a maskset stored area */
+};
+
+struct lkst_maskset_listent {
+	lkst_maskset_id id;			/* maskset ID */
+	char name[LKST_MASKSET_NAME_LEN];	/* maskset name */
+	lkst_maskset_table_len len;	/* total number of maskset entries */
+};
+
+struct lkst_maskset_listparam {
+	lkst_maskset_id current_id;	/* current maskset ID */
+	size_t listent_size;	/* size of the listent */
+	struct lkst_maskset_listent *listent;
+				/* area to store the list of masksets */
+};
+
+
+extern int lkst_maskset_read(struct lkst_maskset_param *maskset_param);
+
+extern int lkst_maskset_write(struct lkst_maskset_param *maskset_param);
+
+extern int lkst_maskset_set(lkst_maskset_id id);
+
+extern int lkst_maskset_delete(lkst_maskset_id id);
+
+extern int lkst_maskset_list(struct lkst_maskset_listparam *lp);
+
+#define LKST_MASKSET_SIZE(n)						\
+	(sizeof(char)*LKST_MASKSET_NAME_LEN +				\
+	     sizeof(lkst_maskset_table_len) +				\
+	     sizeof(struct lkst_maskset_entry) * (n))
+
+#define LKST_MASKSET_LISTENT_SIZE(n)					\
+	     (sizeof(struct lkst_maskset_listent) * (n))
+
+
+#endif				/* _LINUX_LKST_MASKSET_H */
diff -Naur kernel.orig/linux24/include/linux/lkst_private.h kernel/linux24/include/linux/lkst_private.h
--- kernel.orig/linux24/include/linux/lkst_private.h	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/include/linux/lkst_private.h	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,572 @@
+/* $Id: lkst_private.h,v 1.7 2002/06/28 11:27:56 indoh Exp $ */
+/* linux/include/linux/lkst_private.h */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by T.Nakamura <tetsu@crl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#ifndef _LINUX_LKST_PRIVATE_H
+#define _LINUX_LKST_PRIVATE_H
+
+
+#ifndef CMD_LKSTDUMP
+#include <linux/sched.h>
+#include <linux/lkst.h>
+#endif /* ifndef CMD_LKSTDUMP */
+#include <linux/lkst_maskset.h>
+#include <linux/lkst_buffer.h>
+#include <linux/lkst_evhandler.h>
+#ifndef CMD_LKSTDUMP
+#include <linux/kernel_stat.h>
+#include <linux/string.h>
+#endif /* ifndef CMD_LKSTDUMP */
+#include <linux/wait.h>
+
+#include <asm/atomic.h>
+#include <asm/lkst_private.h>
+
+/* recid for CPU */
+typedef int lkst_cpu_recid;
+#define LKST_CPU_RECID_SIZE SMP_CACHE_BYTES/sizeof(lkst_cpu_recid)
+#define LKST_CPU_RECID_BUF_SIZE LKST_CPU_MAX*LKST_CPU_RECID_SIZE
+
+/* buffer size -- must be power of 2 */
+#define LKST_BUFFER_SIZE_DEFAULT	65536
+#define LKST_BUFFER_SIZE_MAX	1073741824	/* 1GByte */
+#define LKST_BUFFER_SIZE_MIN	8192
+
+	/* Rooms for overrun in buffer wrapping around.	
+		   It assumes the worst case that all the CPUs 
+		   interrupt in detection of buffer wrapping,
+		   and exception occurs on each CPU.		*/
+#define LKST_BUFFER_HEADSPACE						\
+	(sizeof (struct lkst_event_record) * LKST_CPU_MAX * 2)
+
+#define LKST_EVHANDLER_BUFFER_TRIAL_MAX		10
+#define LKST_EVHANDLER_MASKSET_TRIAL_MAX	10
+
+#define LKST_DEV_MAJOR	231	/* LKST device major number */  /* TODO */
+#define LKST_DEV_MINOR	0	/* LKST device minor number */
+#define LKST_DEV_NAME	"lkst"	/* LKST device name */
+
+/* LKST buffer version */
+#define LKST_BUF_VER	0x000100	/* major(1B) miner(1B) sub(1B) */
+
+#define LKST_FLAG_YES	1
+#define LKST_FLAG_NO	0
+
+typedef lkst_evhandler_id *lkst_maskset;
+
+struct lkst_maskset_table {
+	char name[LKST_MASKSET_NAME_LEN];
+	lkst_maskset *masksetp;
+	volatile lkst_pointer_check_digit masksetp_check;
+};
+
+
+	/* Size of lkst_event_record is defined in <linux/lkst_buffer.h>, 
+	   as LKST_SIZEOF_LKST_EVENT_RECORD. It must be power of 2.       */
+	/* This value will be verified in initialization of 
+	   LKST in DEBUG mode. */
+struct lkst_event_record {
+	int log_recid;
+	int log_event_type;
+	lkst_tsc_t log_time;
+	pid_t log_pid;
+  	int _reserved0;	     /* Reserved for cpu id - in case shared buffer. */
+	lkst_arg_t log_arg1;
+	lkst_arg_t log_arg2;
+	lkst_arg_t log_arg3;
+	lkst_arg_t log_arg4;
+	lkst_arg_t _reserved1;
+};
+
+typedef void (*lkst_evhandler_func) (void *phookrec, int event_type,
+				     lkst_arg_t arg1,
+				     lkst_arg_t arg2,
+				     lkst_arg_t arg3, lkst_arg_t arg4);
+
+typedef int (*lkst_evhandler_ctrl_func) (void *buf, size_t bufsize);
+
+struct lkst_evhandler_entry {
+	char name[LKST_EVHANDLER_NAME_LEN];
+	volatile lkst_evhandler_func evhandler;
+	volatile lkst_pointer_check_digit evhandler_check;
+	volatile lkst_evhandler_ctrl_func evhandler_ctrl;
+	volatile lkst_pointer_check_digit evhandler_ctrl_check;
+};
+
+struct lkst_elapsed_times_buff {
+	time_t current_time;
+	atomic_t count;
+	int count0;
+	/* average, maximum, minimum and varianceof elapsed times */
+	time_t avg_time;
+	time_t max_time;
+	time_t min_time;
+	time_t var_time;
+	/* room for optional times */
+	time_t o0_time;
+	time_t o1_time;
+	time_t o2_time;
+	time_t o3_time;
+
+	/* room for optional event_types */
+	int event_type0;
+	int event_type1;
+	int event_type2;
+	int event_type3;
+};
+
+struct lkst_event_buffer {
+	atomic_t writep;
+	size_t size;			/* buffer size */
+	size_t readp;
+	lkst_buffer_id id, prev, next;	/* buffer ID of own/prev/next buffer */
+	char _pad1;
+	char eyecatcher[4];		/* EyeCacher */
+	int cpu;			/* cpu number of the buffer */
+	int last_recid;			/* recid of event record read last */
+	size_t last_readp;		/* last readp */
+	struct timeval xtime;		/* xtime */
+	unsigned int cmos_time_flag; 	/* cmos time flag */
+	int buf_ver;			/* LKST buffer version */
+	atomic_t rcnt, wcnt;
+	char _pad2[8];
+	struct lkst_event_record body[LKST_BUFFER_SIZE_DEFAULT /
+				      sizeof(struct lkst_event_record)];
+					/* buffer body */
+};
+
+	//TODO : header size is changed by the architecture.
+struct lkst_header {
+	char eyecacher[4];	/* EyeCacher */
+	atomic_t refcnt;	/* Reference counter of LKST. */
+
+	/* recid for CPU */
+	lkst_cpu_recid cpu_recid[LKST_CPU_RECID_BUF_SIZE];
+
+	/* Current Maskset Pointer */
+	volatile lkst_maskset *current_masksetp;
+	volatile lkst_pointer_check_digit current_masksetp_check;
+	volatile lkst_maskset_id current_maskset_id;
+	/* Needed to be volatile, because the order of modification
+	 *   and reference of these values are significant.
+	 */
+
+	/* Maskset Table */
+	struct lkst_maskset_table maskset_table[LKST_MASKSET_TBL_MAX];
+
+	/* Event Handler Table */
+	struct lkst_evhandler_entry evhandler_table[LKST_EVHANDLER_TBL_MAX];
+
+	/* IDs of current buffers. */
+	lkst_buffer_id current_buffer_id[LKST_CPU_MAX];
+
+	/* Event Buffer Table */
+	struct lkst_buffer_table {
+				// TODO: volatile struct lkst_event_buffer *bufferp;
+		struct lkst_event_buffer *bufferp;
+		/* event_buffer address */
+		lkst_pointer_check_digit bufferp_check;
+	} buffer_table[LKST_BUFFER_TBL_MAX];
+
+
+	/* Below variables are needed for all buffer list.
+	 * In current implementation, each Buffer list is corresponded to CPU.
+	 */
+	/* Tail of Buffer list */
+	lkst_buffer_id buffer_tail[LKST_CPU_MAX];
+	/* Head of Buffer list */
+	lkst_buffer_id buffer_head[LKST_CPU_MAX];
+	/* ring structure flag */
+	unsigned int buffer_ring[LKST_CPU_MAX];
+	/* owner pid of Buffer list */
+	pid_t buffer_owner[LKST_CPU_MAX];
+	/* buffer wait queue */
+	wait_queue_head_t buffer_wq[LKST_CPU_MAX];
+
+	/* Stopped maskset id */
+	lkst_maskset_id maskset_id_saved;
+
+	/* LKST running status flag */
+	atomic_t status_flag;
+
+	/* LKST available memory size */
+	size_t available_memory_size;
+	/* LKST available memory limit address */
+	void *limit_addr;
+
+	int endian_big;			/* byte order, 0 if little endian */
+	lkst_cpu_freq_t	cpu_freq;	/* cpu clockspeed in kHz */
+	lkst_tsc_t tsc;			/* machine cycle */
+	struct timeval xtime;		/* xtime */
+	unsigned int cmos_time_flag; 	/* cmos time flag */
+	int buf_ver;			/* LKST buffer version */
+	char arch[LKST_ARCH_NAME_LEN];	/* Architecture name */
+};
+
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE
+extern __inline__ struct lkst_header *get_lkst(void);
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
+
+extern __inline__ unsigned long lkst_get_cpu_khz(void);
+
+#ifndef CMD_LKSTDUMP
+int lkst_open(struct inode *inode, struct file *filp);
+
+int lkst_close(struct inode *inode, struct file *filp);
+
+ssize_t lkst_read(struct file *filp, char *buf, size_t count, loff_t *ppos);
+
+int lkst_ioctl(struct inode *inode, struct file *filp,
+	       unsigned int request, unsigned long arg);
+
+extern int lkst_evhandler_register(lkst_evhandler_id id, char *name,
+				   lkst_evhandler_func evhandler,
+				   lkst_evhandler_ctrl_func
+				   evhandler_ctrl);
+
+extern void lkst_buffer_dump_current_txt(void);
+
+extern int lkst_evhandlerprim_recid_inc(void);
+extern struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer_cpu(int cpu);
+extern struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer_id(lkst_buffer_id id);
+extern struct lkst_event_buffer
+*lkst_evhandlerprim_select_buffer(void);
+extern struct lkst_event_record
+*lkst_evhandlerprim_get_write_entry(int event_type);
+extern struct lkst_event_buffer
+*lkst_evhandlerprim_getw_buffer_cpu(int cpu);
+extern struct lkst_event_buffer
+*lkst_evhandlerprim_getw_buffer(void);
+extern void
+lkst_evhandlerprim_putw_buffer(struct lkst_event_buffer *buffer);
+extern void lkst_evhandlerprim_daemon_wakeup(int cpu);
+extern void lkst_evhandlerprim_entry_log_l2(int event_type,
+					    lkst_arg_t arg1, lkst_arg_t arg2,
+					    lkst_arg_t arg3, lkst_arg_t arg4);
+
+/* System default event handlers */
+
+extern void lkst_evhandler_default(void *phookrec, int event_type,
+				   lkst_arg_t arg1,
+				   lkst_arg_t arg2,
+				   lkst_arg_t arg3, lkst_arg_t arg4);
+
+extern int lkst_evhandler_default_ctrl(void *buf, size_t buf_size);
+
+extern void lkst_evhandler_buffer_shift(void *phookrec, int event_type,
+					lkst_arg_t arg1,
+					lkst_arg_t arg2,
+					lkst_arg_t arg3,
+					lkst_arg_t arg4);
+
+extern void lkst_evhandler_buffer_shift_dw(void *phookrec, int event_type,
+					   lkst_arg_t arg1,
+					   lkst_arg_t arg2,
+					   lkst_arg_t arg3,
+					   lkst_arg_t arg4);
+
+extern void lkst_evhandler_maskset_xchg(void *phookrec, int event_type,
+					lkst_arg_t arg1,
+					lkst_arg_t arg2,
+					lkst_arg_t arg3,
+					lkst_arg_t arg4);
+
+#if DEBUG
+extern void lkst_evhandler_exception(void *phookrec, int event_type,
+				     lkst_arg_t arg1,
+				     lkst_arg_t arg2,
+				     lkst_arg_t arg3,
+				     lkst_arg_t arg4);
+#endif /* DEBUG */
+
+#endif /* ifndef CMD_LKSTDUMP */
+
+
+				/* entry address indexed in buffer body */
+#define LKST_BUFFER_BODY_INDEX(buffer,index)				\
+	(&(((struct lkst_event_buffer *)(buffer))->body[(index)]))
+
+				/* Top of buffer body */
+#define LKST_BUFFER_BODY_TOP(buffer)					\
+	(LKST_BUFFER_BODY_INDEX((buffer),0))
+
+				/* Offset of buffer body from buffer head */
+#define LKST_BUFFER_BODY_OFFSET()					\
+	((size_t)LKST_BUFFER_BODY_TOP(NULL))
+
+				/* size of the buffer whole */
+#define LKST_BUFFER_AREA_SIZE(n)					\
+	(LKST_BUFFER_BODY_OFFSET() + (n))
+
+#ifdef LKST_DEBUG_PRINTK
+#define DPRINTK(fmt, args...)						\
+	printk(KERN_ERR "LKST(%s): " fmt, __FUNCTION__, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+
+#ifndef CMD_LKSTDUMP
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE
+
+extern char _stext, _etext;
+extern struct module *module_list;
+extern struct module kernel_module;
+
+/*
+ * function lkst_find_module_by_address
+ * Find module in which specified address is contained, and return
+ * pointer to the module.
+ * 
+ *  Caution: This function does not verify value of event_entry_p.
+ * 
+ *  Arguments
+ *    addr {IN}:	address.
+ *
+ *  returns
+ *    address to the module.
+ * 
+ */
+static __inline__ struct module *
+lkst_find_module_by_address_inline(unsigned long addr)
+{
+	struct module *mod;
+
+	if (addr >= (unsigned long) &_stext &&
+	    addr <= (unsigned long) &_etext)
+		return &kernel_module;
+
+	// TODO: avoid conflicts without spin_lock(&modlist_lock);
+
+	for (mod = module_list;
+	     mod != &kernel_module; mod = mod->next) {
+		if (!(mod->flags&MOD_RUNNING))
+			return NULL;
+		if (mod->flags&MOD_DELETED)
+			return NULL;
+		/* mod_bound tests for addr being inside the vmalloc'ed
+		 * module area. Of course it'd be better to test only
+		 * for the .text subset... */
+		if (mod_bound(addr, 0, mod)) {
+			return mod;
+			break;
+		}
+	}
+	/* address was not found. */
+	return NULL;
+}
+extern struct module * lkst_find_module_by_address(unsigned long addr);
+#endif /* ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
+
+
+/*
+ * function lkst_evhandlerprim_entry_next()
+ * A primitive part of an Event-handler. This function write specified record
+ * to specified entry.
+ * 
+ *  Caution: This function does not verify value of event_entry_p.
+ * 
+ *  Arguments
+ *    buffer {OUT}:	address of control block of the buffer to write.
+ *    event_type {IN}:	corresponding event type.
+ *
+ *  returns
+ *    event_entry_p:	address of entry to write.
+ *      NULL		found no entry to write.
+ * 
+ */
+static __inline__ struct lkst_event_record
+*lkst_evhandlerprim_entry_next(struct lkst_event_buffer *buffer,
+			       int event_type)
+{
+	struct lkst_event_record *event_entry_p;
+	size_t writep;
+	size_t sizem = buffer->size - 1;//TODO:
+
+	buffer->writep.counter += sizeof(struct lkst_event_record);
+	writep = ((size_t)(buffer->writep.counter)) & sizem;
+
+				/* Check buffer wrapping. */
+	if (!writep) {
+				/* Wrapped. */
+		if (event_type == LKST_ETYPE_LKST_BUFF_OVFLOW) {
+				/* To avoid infinite loop, retrn NULL
+				   then caller do nothing.		*/
+			return NULL;
+		}
+		else {
+				/* Process buffer-over-flow event. */
+			lkst_entry_log(NULL, LKST_ETYPE_LKST_BUFF_OVFLOW,
+				       buffer->cpu,
+				       buffer->next,
+				       event_type,
+				       LKST_ARGP(buffer));
+		}
+	}
+
+	(char *) event_entry_p =
+		(char *)LKST_BUFFER_BODY_TOP(buffer) + writep;
+
+	return (event_entry_p);
+}
+
+/*
+ * function lkst_evhandlerprim_entry()
+ * A primitive part of an Event-handler. This function write specified record
+ * to specified entry.
+ * 
+ *  Caution: This function does not verify value of event_entry_p.
+ * 
+ *  Arguments
+ *    buffer {OUT}:	address of control block of the buffer to write.
+ *    event_type {IN}:	corresponding event type.
+ *    index {IN}:	index of the entry to write.
+ *
+ *  returns
+ *    event_entry_p:	address of entry to write.
+ *      NULL		found no entry to write.
+ * 
+ */
+static __inline__ struct lkst_event_record
+*lkst_evhandlerprim_entry(struct lkst_event_buffer *buffer,
+			  int event_type, int index)
+{
+	struct lkst_event_record *event_entry_p;
+
+	if (((index + 1) * sizeof(struct lkst_event_record))
+	    > buffer->size)
+		return NULL;
+
+	event_entry_p = LKST_BUFFER_BODY_INDEX(buffer,index);
+
+	return (event_entry_p);
+}
+
+/*
+ * function lkst_evhandlerprim_entry_log_l1
+ * A primitive part of an Event-handler. This function write specified record
+ * to specified entry.
+ * 
+ *  Caution: This function does not verify value of event_entry_p.
+ * 
+ *  Arguments
+ *    event_entry_p {OUT}:
+ *			address of the entry to which the record 
+ *			will be written.
+ *    recid {IN}:	ID of event record to be recorded.
+ *    event_type {IN}:	corresponding event type.
+ *    arg1-4 {IN}:	arguments acquired at a trace point
+ *
+ *  returns
+ *    NONE
+ * 
+ */
+static __inline__ void lkst_evhandlerprim_entry_log_l1(struct lkst_event_record
+						   *event_entry_p, int recid,
+						   int event_type,
+						   lkst_arg_t arg1,
+						   lkst_arg_t arg2,
+						   lkst_arg_t arg3,
+						   lkst_arg_t arg4)
+{
+	event_entry_p->log_time = lkst_evhandlerprim_mc(); /* current time */
+
+	event_entry_p->log_event_type = event_type;
+	event_entry_p->log_pid = current->pid; /* current pid */ ;
+	event_entry_p->log_arg1 = arg1;
+	event_entry_p->log_arg2 = arg2;
+	event_entry_p->log_arg3 = arg3;
+	event_entry_p->log_arg4 = arg4;
+	event_entry_p->log_recid = recid;
+}
+
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE
+/*
+ * function lkst_evhandlerprim_kernel_text_address
+ * A primitive part of an Event-handler. This returns whether
+ * addr is in kernel (or kernel modules) text address.
+ * The body of this primitive is defined in 
+ * include/asm/lkst_private.h as an inlined function named 
+ * lkst_evhandlerprim_kernel_text_address_inline().
+ *
+ *  Arguments
+ *    addr {IN}: address to investigate.
+ *
+ *  returns
+ *    0: addr is out of the kernel code nor kernel module.
+ *    1: addr is in the kernel code or kernel module.
+ *
+ */
+static __inline__ int lkst_evhandlerprim_kernel_text_address(unsigned long addr)
+{
+	return (NULL != lkst_find_module_by_address(addr));
+}
+#endif /*#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE*/
+
+#endif /* ifndef CMD_LKSTDUMP */
+
+
+#define LKST_ETYPE_VERIFY(event_type) 					\
+	(!(0xfffff000&(event_type)))
+
+			/*  p + p##_check == LKST_POINTER_CHECK_MAGIC */
+#define LKST_POINTER_CHECK_VAL(p) 					\
+	(LKST_POINTER_CHECK_MAGIC - ((lkst_pointer_check_digit)(p)))
+			/* initialize p##_check */
+#define LKST_POINTER_CHECK_INIT(p) 					\
+	(p##_check = LKST_POINTER_CHECK_VAL(p))
+			/* copy NULL into p and p##_check*/
+#define LKST_POINTER_INVALIDATE(p)					\
+	(p##_check = (lkst_pointer_check_digit)(0), (void *)(p) = NULL )
+			/* verify p and p##_check */
+#define LKST_POINTER_VERIFY_STRICT(p1, p2)				\
+	((p2) = (p1),							\
+	 (void *)(p1##_check) == (void *)LKST_POINTER_CHECK_VAL((p2)))
+#define LKST_POINTER_VERIFY(p1, p2) LKST_POINTER_VERIFY_STRICT(p1, p2)
+#define LKST_POINTER_VERIFY_HP(p1, p2)					\
+	((p2) = (p1), 1)
+
+#define	LKST_MASKSET_QUERY_EVHANDLER_ID(maskset_ptr, event_type)	\
+	(((lkst_evhandler_id *)(maskset_ptr))[(event_type)])
+#define	LKST_MASKSET_SET_EVHANDLER_ID(maskset_ptr, event_type, id)	\
+	(((lkst_evhandler_id *)(maskset_ptr))[(event_type)] = (id))
+
+#define	LKST_MASKSET_TABLE_ENTRY_SET(table, id, maskname, addr) ({     	\
+	(table)[(id)].masksetp = (lkst_maskset *)(addr);		\
+	strncpy((table)[(id)].name, (maskname),				\
+		(size_t) LKST_MASKSET_NAME_LEN);			\
+	(table)[id].name[LKST_MASKSET_NAME_LEN-1] = '\0';		\
+	LKST_POINTER_CHECK_INIT((table)[(id)].masksetp); })
+
+#define	LKST_MASKSET_SET_CURRENT(id) ({					\
+	lkst.current_maskset_id = (id);					\
+	lkst.current_masksetp =						\
+		lkst.maskset_table[(id)].masksetp;			\
+	LKST_POINTER_CHECK_INIT(lkst.current_masksetp);})
+
+#define LKST_BUFFER_PREV_ENTRY(buffer, pt, size)			\
+	((struct lkst_event_record *) ((char *) (buffer) +		\
+	(((pt) - sizeof(struct lkst_event_record)) & (size - 1))))
+
+#define LKST_BUFFER_READP_RESET(buffer)	({				\
+	(buffer)->readp = LKST_BUFFER_HEADSPACE;			\
+	(buffer)->last_readp =						\
+		((buffer)->readp - sizeof(struct lkst_event_record)) &	\
+	   	((buffer)->size - 1);					\
+	(buffer)->last_recid =						\
+		((struct lkst_event_record *)				\
+		((char *) ((buffer)->body)				\
+			 + (buffer)->last_readp))->log_recid;})
+
+#endif /* _LINUX_LKST_PRIVATE_H */
diff -Naur kernel.orig/linux24/include/linux/vmalloc.h kernel/linux24/include/linux/vmalloc.h
--- kernel.orig/linux24/include/linux/vmalloc.h	Fri Nov 23 04:46:20 2001
+++ kernel/linux24/include/linux/vmalloc.h	Fri Jun 28 20:57:45 2002
@@ -7,6 +7,8 @@
 
 #include <asm/pgtable.h>
 
+#include <linux/lkst.h>
+
 /* bits in vm_struct->flags */
 #define VM_IOREMAP	0x00000001	/* ioremap() and friends */
 #define VM_ALLOC	0x00000002	/* vmalloc() */
@@ -32,7 +34,17 @@
  
 static inline void * vmalloc (unsigned long size)
 {
-	return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+	void * addr;
+
+	addr = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+
+	LKST_HOOK_INLINE(LKST_ETYPE_MEM_VMALLOC,
+		       LKST_ARG32(addr, 0),
+		       LKST_ARG32(size, 0),
+		       LKST_ARG32(__builtin_return_address(0), 0),
+		       LKST_ARG32(0, 0));
+
+	return addr;
 }
 
 /*
diff -Naur kernel.orig/linux24/init/main.c kernel/linux24/init/main.c
--- kernel.orig/linux24/init/main.c	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/init/main.c	Fri Jun 28 20:57:45 2002
@@ -70,6 +70,10 @@
 #include <asm/smp.h>
 #endif
 
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE
+#include <linux/lkst.h>
+#endif /* ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE */
+
 /*
  * Versions of gcc older than that listed below may actually compile
  * and link okay, but the end product can have subtle run time bugs.
@@ -560,6 +564,9 @@
  * enable them
  */
 	lock_kernel();
+#if (defined(CONFIG_DEBUG_KERNEL_STATE_TRACE)&&defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_IN_START))
+        lkst_trc_init_stage0();
+#endif /* if (defined(CONFIG_DEBUG_KERNEL_STATE_TRACE)&&defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_IN_START)) */
 	printk(linux_banner);
 	setup_arch(&command_line);
 	printk("Kernel command line: %s\n", saved_command_line);
@@ -605,6 +612,9 @@
 	pgtable_cache_init();
 
 	mempages = num_physpages;
+#if (defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)) && defined(__i386__)
+	lkst_dummy_vmalloc();
+#endif /* (CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE) && __i386__ */
 
 	fork_init(mempages);
 	proc_caches_init();
@@ -633,6 +643,9 @@
 	 *	make syscalls (and thus be locked).
 	 */
 	smp_init();
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE
+	lkst_trc_init_main();
+#endif /* ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE */
 	rest_init();
 }
 
diff -Naur kernel.orig/linux24/kernel/Makefile kernel/linux24/kernel/Makefile
--- kernel.orig/linux24/kernel/Makefile	Mon Sep 17 13:22:40 2001
+++ kernel/linux24/kernel/Makefile	Fri Jun 28 20:57:45 2002
@@ -9,17 +9,20 @@
 
 O_TARGET := kernel.o
 
-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
+export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o lkst_kernel.o hook.o
 
 obj-y     = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
 	    sysctl.o acct.o capability.o ptrace.o timer.o user.o \
-	    signal.o sys.o kmod.o context.o
+	    signal.o sys.o kmod.o context.o lkst_kernel.o
 
+obj-$(CONFIG_HOOK) += hook.o
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += ksyms.o
 obj-$(CONFIG_PM) += pm.o
 
+CFLAGS_lkst_kernel.o += -DUTS_MACHINE='"$(ARCH)"'
+
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
 # needed for x86 only.  Why this used to be enabled for all architectures is beyond
diff -Naur kernel.orig/linux24/kernel/hook.c kernel/linux24/kernel/hook.c
--- kernel.orig/linux24/kernel/hook.c	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/kernel/hook.c	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,656 @@
+/*****************************************************************************/
+/* Kernel Hooks Interface.                                    		     */
+/* Version 1.2                                                               */
+/* Author: Richard J Moore richardj_moore@uk.ibm.com                         */
+/* 	   Vamsi Krishna S. r1vamsi@in.ibm.com 				     */
+/*                                                                           */
+/* Implementation of the kernel hooks interface.			     */
+/*                                                                           */
+/* Refer to Documentation/hook/HOWTO for details.                            */
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/hook.h>
+
+static spinlock_t hook_lock = SPIN_LOCK_UNLOCKED;
+
+static int hook_global_status = 0;
+static hook_head_t *last_hook_head;
+static hook_head_t *first_hook_head;
+static struct proc_dir_entry *proc_hooks_dir;
+#define PROC_HOOKS_ROOT "hooks"
+
+static int hook_default_exit(hook_rec_t * phookrec, unsigned int cParms, ...)
+{
+#ifdef HOOK_DEBUG
+	int i;
+	DPRINTK("cParms: %u pHook_record: 0x%08x\n", cParms, (unsigned int) phookrec);
+	for(i = 1; i <= cParms; ++i)
+		DPRINTK("Parm%u: %u\n", i, *(int *) *(&cParms + i));
+#endif
+	return HOOK_TERMINATE;
+}
+
+/* internal subroutines called by the public interfaces:
+   hook_exit_register
+   hook_exit_deregister
+   hook_exit_arm
+   hook_exit_disarm
+   hook_initialise
+   hook_terminate
+*/
+
+static void calculate_indicies(hook_head_t * phhr)
+{
+	hook_rec_t *phr;
+ 	/* recalculate indicies */
+	for(phr = phhr->hook_next; phr != (hook_rec_t *) phhr; phr = phr->hook_next) {
+		phr->hook_index = (phr->hook_prev->hook_index) + 1;
+	}
+	return;
+}
+
+static inline void deactivate_hook(hook_head_t * phookhead)
+{
+	phookhead->hook_flags &= ~HOOK_HEAD_ACTIVE;
+	if(phookhead->hook_flags & HOOK_HEAD_ASM_HOOK)
+		deactivate_asm_hook(phookhead);
+}
+
+static inline void activate_hook(hook_head_t * phookhead)
+{
+	phookhead->hook_flags |= HOOK_HEAD_ACTIVE;
+	if(phookhead->hook_flags & HOOK_HEAD_ASM_HOOK)
+		activate_asm_hook(phookhead);
+}
+
+static void disarm_one_hook_exit(hook_rec_t * phookrec)
+{
+	int found = FALSE;
+	hook_rec_t *phr;
+
+	phookrec->hook_flags &= ~HOOK_ARMED;
+
+	/* see if there are any armed exits still present for this hook */
+	for(phr = phookrec->hook_head->hook_next; phr != (hook_rec_t *) phookrec->hook_head;
+	    phr = phr->hook_next) {
+
+		if(phr->hook_flags & HOOK_ARMED) {
+			found = TRUE;
+			break;
+		}
+	}
+
+	/* deactivate hook if no armed exits remain */
+	if(!found) {
+		deactivate_hook(phr->hook_head);
+	}
+	return;
+}
+
+/* validate input hook registeration record */
+static int validate_input_hook_rec(hook_rec_t * phookrec)
+{
+        if(phookrec->hook_flags & ~HOOK_VALID_USER_FLAGS) {
+		DPRINTK("Invalid hook_flags %08x\n", phookrec->hook_flags);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if(!(phookrec->hook_exit)) {
+		DPRINTK("Invalid hook_exit %08x\n", phookrec->hook_exit);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if((phookrec->hook_next)) {
+		DPRINTK("Invalid hook_nextflags %08x\n", phookrec->hook_next);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if((phookrec->hook_prev)) {
+		DPRINTK("Invalid hook_prev %08x\n", phookrec->hook_prev);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if((phookrec->hook_index)) {
+		DPRINTK("Invalid hook_index %08x\n", phookrec->hook_index);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if((phookrec->hook_head)) {
+		DPRINTK("Invalid hHead %08x\n", phookrec->hook_head);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	return 0;
+}
+
+/* validate a current hook registeration record*/
+static int validate_hook_rec(hook_rec_t * phookrec)
+{
+	if(!(phookrec->hook_flags & HOOK_REGISTERED)) {
+		DPRINTK("Invalid hook_flags %08x\n", phookrec->hook_flags);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if(!(phookrec->hook_exit)) {
+		DPRINTK("Invalid hook_exit %08x\n", phookrec->hook_exit);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if(!(phookrec->hook_next)) {
+		DPRINTK("Invalid hook_next %08x\n", phookrec->hook_next);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if(!(phookrec->hook_prev)) {
+		DPRINTK("Invalid hook_prev %08x\n", phookrec->hook_prev);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if(!(phookrec->hook_index)) {
+		DPRINTK("Invalid hook_index %08x\n", phookrec->hook_index);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	if(!(phookrec->hook_head)) {
+		DPRINTK("Invalid hook_head %08x\n", phookrec->hook_head);
+		return ERROR_INVALID_REGISTRATION_RECORD;
+	}
+	return 0;
+}
+
+/* common read/write routines for procfs entries */
+static int hook_read_proc(char *page, char **start, off_t off, int count, 
+		int *eof, void *data)
+{
+	int len;
+	hook_rec_t *phookrec = (hook_rec_t *)data;
+	len = sprintf(page, "%d\n", (phookrec->hook_flags & HOOK_ARMED));
+	return len;
+}
+
+static int hook_write_proc(struct file *file, const char *buffer, 
+		unsigned long count, void *data)
+{
+	hook_rec_t *phookrec = (hook_rec_t *)data;
+	hook_rec_t *old_link = phookrec->hook_link;
+	char input;
+	int armed;
+
+	if (copy_from_user(&input, buffer, 1)) {
+		return -EFAULT;
+	}
+	armed = input - '0';
+	if (armed && !(phookrec->hook_flags & HOOK_ARMED)) {
+		hook_exit_arm(phookrec);
+	} else if (!armed && (phookrec->hook_flags & HOOK_ARMED)) {
+		hook_exit_disarm(phookrec);
+	}
+	phookrec->hook_link = old_link;
+	return count; /* dont want to read anymore */
+}
+
+static int hook_create_proc(hook_rec_t * phookrec, int proc_writable)
+{
+	char *proc_entry_name;
+	hook_head_t *phhr = (hook_head_t *) (phookrec->hook_head);
+
+	if (phhr->proc_entry) {
+		char tmp[32];
+		proc_entry_name = phookrec->hook_exit_name;
+		if (!proc_entry_name) {
+			sprintf(tmp, "%p", phookrec);
+			proc_entry_name = tmp;
+		}
+		if (!proc_writable) {
+			phookrec->proc_entry = create_proc_read_entry(
+					proc_entry_name, 0444, 
+					phhr->proc_entry, 
+					hook_read_proc,
+					phookrec);
+		} else {
+			phookrec->proc_entry = create_proc_entry(
+					proc_entry_name, 0644, 
+					phhr->proc_entry);
+			if (phookrec->proc_entry) {
+				phookrec->proc_entry->data = phookrec;
+				phookrec->proc_entry->read_proc = hook_read_proc;
+				phookrec->proc_entry->write_proc = hook_write_proc;
+			}
+		}
+	}
+}
+
+/* public interfaces being here ... */
+
+int _hook_exit_register(char *hookid, hook_rec_t * phookrec, int proc_writable)
+{
+	hook_head_t *phhr;
+	hook_rec_t *phr;
+	int found;
+	int rc;
+	unsigned long eflags;
+
+	if(!(hook_global_status & HOOK_INIT))
+		return ERROR_GKHI_UNAVAILABLE;
+
+        rc = validate_input_hook_rec(phookrec);
+	if (rc)
+		return rc;
+
+	/* from this point we depend on GKHI structure consistency */
+	spin_lock_irqsave(&hook_lock, eflags);
+
+	/* locate the corresponding hookhead */
+	found = FALSE;
+	for(phhr = first_hook_head; phhr; phhr = phhr->hook_head_next) {
+		if(strcmp(hookid, phhr->hook_id) == 0) {
+			found = TRUE;
+			break;
+		}
+	}
+
+	if(!found) {
+		spin_unlock_irqrestore(&hook_lock, eflags);
+		return ERROR_HOOK_NOT_FOUND;
+	}
+
+	/* check for priority special conditions and determine the insertion
+	 * point. Note if scheduling priority is not specified then exits are
+	 * dispatched in FIFO order unless the LIFO flag is set, in which
+	 * case the hook record is inseted at the head of the queue.
+	 */
+	phr = (hook_rec_t *) phhr;
+
+	/*
+	 * If the hook head is defined as an exclusive hook, force
+	 * the hookrec flags to be exclusive.
+	 */
+	if(phhr->hook_flags & HOOK_HEAD_EXCLUSIVE) {
+		phookrec->hook_flags |= HOOK_PRIORITY_EXCLUSIVE;
+	}
+	
+	if((phookrec->hook_flags) & HOOK_PRIORITY_FIRST) {
+		if(phhr->hook_next != (hook_rec_t *) phhr) {
+			if((phhr->hook_next->hook_flags) & HOOK_PRIORITY_FIRST) {
+				spin_unlock_irqrestore(&hook_lock, eflags);
+				return ERROR_HIGHER_PRIORITY_HOOK;
+			}
+		}
+	}
+
+	if((phookrec->hook_flags) & HOOK_PRIORITY_LAST) {
+		if(phhr->hook_next != (hook_rec_t *) phhr) {
+			if((phhr->hook_prev->hook_flags) & HOOK_PRIORITY_LAST) {
+				spin_unlock_irqrestore(&hook_lock, eflags);
+				return ERROR_LOWER_PRIORITY_HOOK;
+			} else {
+				phr = phhr->hook_prev;
+			}
+		}
+	}
+
+	if(!((phookrec->hook_flags) & HOOK_PRIORITY)) {
+		if((phookrec->hook_flags) & HOOK_QUEUE_LIFO) {
+			if((phhr->hook_next->hook_flags) & HOOK_PRIORITY_FIRST)
+				phr = phhr->hook_next;
+		} else if((phhr->hook_prev->hook_flags) & HOOK_PRIORITY_LAST)
+			phr = phhr->hook_prev->hook_prev;
+		else
+			phr = phhr->hook_prev;
+
+	}
+
+	/*
+	 * phr points to the hook record after which we make the insertion -
+	 * insert into circular double-linked list
+	 */
+	phookrec->hook_next = phr->hook_next;
+	phr->hook_next = phookrec;
+	phookrec->hook_prev = phr;
+	phookrec->hook_next->hook_prev = phookrec;
+
+	/* set output fields */
+
+	/* link back to head */
+	(hook_head_t *) (phookrec->hook_head) = phhr;
+
+	/* recalculate indicies */
+	calculate_indicies(phookrec->hook_head);
+
+	/* 
+	 * create proc entry if exit name is specified 
+	 * and a proc entry exists for the hook head exits. 
+	 */
+	if(!(hook_global_status & HOOK_IN_START)) {
+		hook_create_proc(phookrec, proc_writable);
+	}
+	else {
+		phookrec->proc_writable = proc_writable;
+	}
+
+	/* optimization for exclusive hooks */
+	if (phhr->hook_flags & HOOK_HEAD_EXCLUSIVE) {
+		phhr->hook_exit = phookrec->hook_exit;
+	}
+
+	/* indicate registration compete */
+	phookrec->hook_flags |= HOOK_REGISTERED;
+
+	spin_unlock_irqrestore(&hook_lock, eflags);
+	return NO_ERROR;
+}
+
+int hook_exit_deregister(hook_rec_t * phookrec)
+{
+	hook_rec_t *phr;
+	int rc;
+	unsigned long eflags;
+	char *proc_entry_name;
+
+	if(!(hook_global_status & HOOK_INIT))
+		return ERROR_GKHI_UNAVAILABLE;
+
+	/* from this point we depend on GKHI structure consistency */
+	spin_lock_irqsave(&hook_lock, eflags);
+	for(phr = phookrec; phr; phr = phr->hook_link) {
+		rc = validate_hook_rec(phr);
+		if (rc) {
+			spin_unlock_irqrestore(&hook_lock, eflags);
+			return rc;
+		}
+
+		/* disarm if armed */
+		if(phr->hook_flags & HOOK_ARMED)
+			disarm_one_hook_exit(phr);
+
+		/* unlink from chain head */
+		phr->hook_prev->hook_next = phr->hook_next;
+		phr->hook_next->hook_prev = phr->hook_prev;
+
+		/* re-calculate indicies.
+		 * Note this is possibly inefficient to do this here if more than
+		 * one exit is deregistered from a single hook. But that should be
+		 * unlikely since a kernel module would normaly register or deregister
+		 * one exit per hook.
+		 */
+		calculate_indicies(phr->hook_head);
+
+		/* cleanup proc entry, if any */
+		if (phr->proc_entry) {
+			char tmp[32];
+			proc_entry_name = phr->hook_exit_name;
+			if (!proc_entry_name) {
+				sprintf(tmp, "%p", phookrec);
+				proc_entry_name = tmp;
+			}
+			phr->proc_entry->data = NULL;
+			remove_proc_entry(proc_entry_name, phr->hook_head->proc_entry);
+		}
+
+		/* optimization for exclusive hooks */
+		if (phr->hook_head->hook_flags & HOOK_HEAD_EXCLUSIVE) {
+			phr->hook_head->hook_exit = &hook_default_exit;
+		}
+
+		/* indicate deregistration compete */
+		phr->hook_flags &= ~HOOK_REGISTERED;
+
+	}
+	spin_unlock_irqrestore(&hook_lock, eflags);
+	return NO_ERROR;
+}
+
+int hook_exit_arm(hook_rec_t * phookrec)
+{
+	hook_rec_t *phr;
+	int rc;
+	unsigned long eflags;
+
+	if(!(hook_global_status & HOOK_INIT))
+		return ERROR_GKHI_UNAVAILABLE;
+
+	/* from this point we depend on GKHI structure consistency */
+	spin_lock_irqsave(&hook_lock, eflags);
+	for(phr = phookrec; phr; phr = phr->hook_link) {
+		rc = validate_hook_rec(phr);
+		if (rc) {
+			spin_unlock_irqrestore(&hook_lock, eflags);
+			return rc;
+		}
+
+		/* mark armed */
+		phr->hook_flags |= HOOK_ARMED;
+
+		/* activate hook if not already active */
+		if(!(phr->hook_head->hook_flags & HOOK_HEAD_ACTIVE)) {
+			activate_hook(phr->hook_head);
+		}
+
+	}
+	spin_unlock_irqrestore(&hook_lock, eflags);
+	return NO_ERROR;
+}
+
+int hook_exit_disarm(hook_rec_t * phookrec)
+{
+	hook_rec_t *phr;
+	int rc;
+	unsigned long eflags;
+
+	if(!(hook_global_status & HOOK_INIT))
+		return ERROR_GKHI_UNAVAILABLE;
+
+	/* from this point we depend on GKHI structure consistency */
+	spin_lock_irqsave(&hook_lock, eflags);
+	for(phr = phookrec; phr; phr = phr->hook_link) {
+		rc = validate_hook_rec(phr);
+		if (rc) {
+			spin_unlock_irqrestore(&hook_lock, eflags);
+			return rc;
+		}
+
+		/* make sure that it is armed */
+		if(!(phr->hook_flags & HOOK_ARMED)) {
+			spin_unlock_irqrestore(&hook_lock, eflags);
+			DPRINTK("Invalid hook_flags %08x\n", phookrec->hook_flags);
+			return ERROR_INVALID_REGISTRATION_RECORD;
+		}
+		disarm_one_hook_exit(phr);
+	}
+	spin_unlock_irqrestore(&hook_lock, eflags);
+	return NO_ERROR;
+}
+
+int _hook_initialise(hook_head_t * phookhead)
+{
+	hook_head_t *phhr;
+	unsigned char *phookloc = (unsigned char *)(phookhead->hook_loc);
+	int found;
+	int rc;
+	unsigned long eflags;
+
+	if(!(hook_global_status & HOOK_INIT))
+		return ERROR_GKHI_UNAVAILABLE;
+
+	rc = is_asm_hook(phookloc);
+	if(rc) {
+	       if(rc == 1) 
+			phookhead->hook_flags |= HOOK_HEAD_ASM_HOOK;
+		else
+			return rc;
+	}
+
+	/* from this point we depend on GKHI structure consistency */
+	spin_lock_irqsave(&hook_lock, eflags);
+
+	/* ensure hookid is not in use */
+	found = FALSE;
+	for(phhr = first_hook_head; phhr; phhr = phhr->hook_head_next) {
+		if(strcmp(phookhead->hook_id, phhr->hook_id) == 0) {
+			found = TRUE;
+			break;
+		}
+	}
+
+	if(found) {
+		spin_unlock_irqrestore(&hook_lock, eflags);
+		return ERROR_HOOK_EXISTS;
+	}
+
+	/* link and initialise new hookhead */
+	phookhead->hook_exit = &hook_default_exit;
+	phookhead->hook_next = (hook_rec_t *) phookhead;
+	phookhead->hook_prev = (hook_rec_t *) phookhead;
+	phookhead->hook_flags |= HOOK_ARMED;
+	phookhead->hook_link = NULL;
+	phookhead->hook_head = phookhead;
+	phookhead->hook_index = 0;
+	phookhead->hook_head_next = NULL;
+	phookhead->hook_loc = phookloc;
+
+	if(!(hook_global_status & HOOK_IN_START)) {
+		phookhead->proc_entry = proc_mkdir(phookhead->hook_id, proc_hooks_dir);
+	}
+
+	/* chain to last hookhead or initialise first and last hookhead pointers */
+	if(last_hook_head)
+		last_hook_head->hook_head_next = phookhead;
+	else
+		first_hook_head = phookhead;
+	last_hook_head = phookhead;
+
+	spin_unlock_irqrestore(&hook_lock, eflags);
+	return NO_ERROR;
+}
+
+int _hook_terminate(hook_head_t * phookhead, int force)
+{
+	hook_head_t *phhr;
+	hook_head_t *pprevhhr;
+	int found;
+	unsigned long eflags;
+
+	if(!(hook_global_status & HOOK_INIT))
+		return ERROR_GKHI_UNAVAILABLE;
+
+	/* from this point we depend on GKHI structure consistency */
+	spin_lock_irqsave(&hook_lock, eflags);
+
+	/* verify hookhead structure is in the chain of hookheads */
+	found = FALSE;
+	pprevhhr = NULL;
+	for(phhr = first_hook_head; phhr; phhr = phhr->hook_head_next) {
+		if(phhr == phookhead) {
+			found = TRUE;
+			break;
+		}
+		pprevhhr = phhr;
+	}
+
+	if(!found) {
+		spin_unlock_irqrestore(&hook_lock, eflags);
+		return ERROR_HOOK_NOT_FOUND;
+	}
+
+	if(phhr->hook_flags & HOOK_HEAD_ACTIVE) {
+		if(force) {
+			deactivate_hook(phhr);
+		} else {
+			spin_unlock_irqrestore(&hook_lock, eflags);
+			return ERROR_HOOK_IS_ACTIVE;
+		}
+	}
+
+	if (phhr->proc_entry) {
+		remove_proc_entry(phhr->hook_id, proc_hooks_dir);
+	}
+
+	/* remove from chain */
+	if(pprevhhr)
+		pprevhhr->hook_head_next = phhr->hook_head_next;
+	if(phhr == last_hook_head)
+		last_hook_head = pprevhhr;
+	if(phhr == first_hook_head)
+		first_hook_head = phhr->hook_head_next;
+
+	spin_unlock_irqrestore(&hook_lock, eflags);
+	return NO_ERROR;
+}
+
+int hook_init_in_start(void)
+{
+	hook_global_status = 0;
+	hook_global_status |= HOOK_INIT;
+	hook_global_status |= HOOK_IN_START;
+	/* @@: for kernel hooks, add hook_initialise statement here. */
+
+	printk(KERN_INFO "Generalised Kernel Hooks Interface 1.4\n");
+	DPRINTK("Debug version active\n");
+	return 0;
+}
+
+static int __init hook_init_module(void)
+{
+	hook_head_t *phookhead;
+	hook_rec_t *phookrec;
+	unsigned long eflags;
+	int ret = 0;
+	if(!(hook_global_status & HOOK_IN_START)) {
+		spin_lock_irqsave(&hook_lock, eflags);
+		proc_hooks_dir = proc_mkdir(PROC_HOOKS_ROOT, NULL);
+		ret = hook_init_in_start();
+		spin_unlock_irqrestore(&hook_lock, eflags);
+	}
+	else {
+		spin_lock_irqsave(&hook_lock, eflags);
+		hook_global_status &= ~HOOK_IN_START;
+
+		/* Hooks has been already initialized. Now make proc entry. */
+		proc_hooks_dir = proc_mkdir(PROC_HOOKS_ROOT, NULL);
+		for(phookhead = first_hook_head; phookhead; phookhead = (phookhead->hook_head_next)) {
+			phookhead->proc_entry = proc_mkdir(phookhead->hook_id, proc_hooks_dir);
+			for(phookrec = phookhead->hook_next;
+			    phookrec != (hook_rec_t *) phookhead; phookrec = phookrec->hook_next) {
+					hook_create_proc(phookrec, phookrec->proc_writable);
+			}
+		}
+		spin_unlock_irqrestore(&hook_lock, eflags);
+	}
+	return ret;
+}
+
+static void __exit hook_cleanup_module(void)
+{
+	hook_head_t *phookhead;
+	hook_rec_t *phookrec;
+	unsigned long eflags;
+
+	spin_lock_irqsave(&hook_lock, eflags);
+
+	/* deactivate each hook */
+	for(phookhead = first_hook_head; phookhead; phookhead = (phookhead->hook_head_next)) {
+		/* disarm and de-register each hook exit */
+		for(phookrec = phookhead->hook_next;
+		    phookrec != (hook_rec_t *) phookhead; phookrec = phookrec->hook_next) {
+        			phookrec->hook_flags &= ~(HOOK_REGISTERED | HOOK_ARMED);
+		}
+		if(phookhead->hook_flags & HOOK_HEAD_ACTIVE) {
+			deactivate_hook(phookhead);
+		}
+	}
+
+	remove_proc_entry(PROC_HOOKS_ROOT, NULL);
+
+	spin_unlock_irqrestore(&hook_lock, eflags);
+	printk(KERN_INFO "Generalised Kernel Hooks Interface 1.4 terminated\n");
+	return;
+}
+
+module_init(hook_init_module);
+module_exit(hook_cleanup_module);
+
+EXPORT_SYMBOL(hook_exit_deregister);
+EXPORT_SYMBOL(hook_exit_arm);
+EXPORT_SYMBOL(hook_exit_disarm);
+EXPORT_SYMBOL(_hook_initialise);
+EXPORT_SYMBOL(_hook_terminate);
+EXPORT_SYMBOL(_hook_exit_register);
+EXPORT_SYMBOL(hook_init_in_start);
diff -Naur kernel.orig/linux24/kernel/lkst_kernel.c kernel/linux24/kernel/lkst_kernel.c
--- kernel.orig/linux24/kernel/lkst_kernel.c	Thu Jan  1 09:00:00 1970
+++ kernel/linux24/kernel/lkst_kernel.c	Fri Jun 28 20:57:45 2002
@@ -0,0 +1,287 @@
+/* $Id: lkst_kernel.c,v 1.2 2002/06/28 11:27:56 indoh Exp $ */
+/* linux/kernel/lkst.c */
+
+/************************************************************
+ *
+ * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
+ * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
+ *            HITACHI CENTRAL RESEARCH LABORATORY.
+ *
+ * Created by K.SERIZAWA <serizawa@sdl.hitachi.co.jp>
+ *
+ ************************************************************/
+
+#include <linux/module.h>
+#include <linux/lkst_private.h>
+#include <linux/vmalloc.h>
+
+EXPORT_SYMBOL(lkst_entry_log);
+
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE
+#undef	DEBUG
+#endif
+
+#define LKST_DEBUG_LOG(ty, a1, a2, a3, a4)
+
+#define MASKSET_TBL_INIT {"", NULL, (lkst_pointer_check_digit) 0}
+#define EVHANDLER_TBL_INIT {"", NULL, (lkst_pointer_check_digit) 0, NULL}
+#define CUR_BUF_INIT {NULL, (lkst_pointer_check_digit) 0, 0,(lkst_pointer_check_digit) 0}
+
+struct lkst_header lkst = {
+	eyecacher:		{'L','K','S','T'},
+	refcnt:			ATOMIC_INIT(0),
+	cpu_recid:		{[0 ... (LKST_CPU_RECID_BUF_SIZE-1)] = 1},
+	current_masksetp:	NULL,
+	current_masksetp_check:	(lkst_pointer_check_digit) 0,
+	current_maskset_id:	0,
+	maskset_table: 		{MASKSET_TBL_INIT, 
+				 MASKSET_TBL_INIT,
+				 MASKSET_TBL_INIT},
+	evhandler_table:	{[0 ... LKST_EVHANDLER_ID_MAX] = EVHANDLER_TBL_INIT},
+	current_buffer_id:	{[0 ... (LKST_CPU_MAX - 1)] = LKST_BUFFER_ID_VOID},
+	buffer_table:		{{NULL, (lkst_pointer_check_digit) 0}},
+	buffer_tail:		{0},
+	buffer_head:		{0},
+	buffer_ring:		{0},
+	buffer_owner: 		{0},
+	buffer_wq:		{{{0}, {0}}},
+	maskset_id_saved:	LKST_MASKSET_ID_RDEFAULT,
+	status_flag:		ATOMIC_INIT(0), /*obsolate , not used*/
+	available_memory_size:	0,
+	limit_addr:		NULL,
+	endian_big:		LKST_BIG_ENDIAN, /* 1 means BIG_ENDIAN. */
+	cpu_freq:		0,
+	tsc:			0,
+	xtime:			{0 ,0},
+	cmos_time_flag:		1,
+	buf_ver:		LKST_BUF_VER,
+	arch:			{UTS_MACHINE},
+};
+
+void lkst_entry_log(void *phookrec, int event_type, lkst_arg_t arg1, lkst_arg_t arg2, 
+					lkst_arg_t arg3, lkst_arg_t arg4)
+{
+	lkst_evhandler_id evhandler_id;
+	volatile lkst_maskset *maskset;
+	lkst_evhandler_func evhandler;
+
+	if (!LKST_ETYPE_VERIFY(event_type))
+		return;
+
+	atomic_inc(&(lkst.refcnt));
+
+#if DEBUG
+	{
+		int i = LKST_EVHANDLER_MASKSET_TRIAL_MAX;
+
+		/* spin while another cpu may change maskset. */
+		while (!LKST_POINTER_VERIFY_STRICT
+		       (lkst.current_masksetp, maskset)) {
+			if (!--i) {
+				LKST_DEBUG_LOG(event_type + 0x200, arg1,
+					(unsigned int) (lkst.current_masksetp),
+					(unsigned int) (lkst.current_masksetp_check),
+					(unsigned int) 0);
+				goto out;
+			}
+		}
+	}
+#else /* !DEBUG */
+	if (!LKST_POINTER_VERIFY_STRICT(lkst.current_masksetp, maskset)) {
+		LKST_DEBUG_LOG(event_type + 0x200, arg1,
+			       (unsigned int) (lkst.current_masksetp),
+			       (unsigned int) (lkst.current_masksetp_check),
+			       (unsigned int) 0);
+		goto out;
+	}
+#endif /* DEBUG */
+
+	evhandler_id = LKST_MASKSET_QUERY_EVHANDLER_ID(maskset, event_type);
+	if (evhandler_id > LKST_EVHANDLER_ID_MAX)
+		goto out;
+
+	if (!LKST_POINTER_VERIFY
+	    (lkst.evhandler_table[evhandler_id].evhandler, evhandler)) {
+		LKST_DEBUG_LOG(event_type + 0x400, evhandler_id,
+			       (unsigned int) (evhandler),
+			       (unsigned int) (lkst.evhandler_table[evhandler_id].evhandler_check),
+			       (unsigned int) 0);
+		goto out;
+	}
+
+			/* Avoid infinate loop. */
+	if (evhandler == lkst_entry_log)
+		goto out;
+
+	(*evhandler) (NULL, event_type, arg1, arg2, arg3, arg4);
+
+out:
+	atomic_dec(&(lkst.refcnt));
+	return;
+}
+
+/*
+ * function lkst_time_set
+ * This function sets time stamp of LKST header.
+ * 
+ *  Arguments
+ *    from_settimeofday : flag shows to be called from do_sys_settimeofday().
+ *  returns
+ *    NONE
+ * 
+ */
+void lkst_time_set(int from_settimeofday)
+{
+	unsigned long flags;
+
+	LKST_CLI(flags);
+	if (from_settimeofday)
+		lkst.cmos_time_flag = 0;
+	get_fast_time(&lkst.xtime);
+	lkst.tsc = lkst_evhandlerprim_mc();
+	LKST_STI(flags);
+}
+EXPORT_SYMBOL(lkst_time_set);
+
+
+/*
+ * This function is called by lkst modules to get
+ * variable "cpu_khz" from LKST_GET_CPU_KHZ().
+ * In some arch, LKST will not provide this function.
+ */
+#ifdef	LKST_GET_CPU_KHZ
+lkst_cpu_freq_t lkst_get_cpu_khz(void)
+{
+	return LKST_GET_CPU_KHZ();
+}
+EXPORT_SYMBOL(lkst_get_cpu_khz);
+#endif /* ifdef	LKST_GET_CPU_KHZ */
+
+
+#ifdef CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE
+inline struct lkst_header *get_lkst(void)
+{
+	return &lkst;
+}
+EXPORT_SYMBOL(get_lkst);
+
+/*
+ * function lkst_find_module_by_address
+ * Find module in which specified address is contained, and return
+ * pointer to the module.
+ * 
+ *  Caution: This function does not verify value of event_entry_p.
+ * 
+ *  Arguments
+ *    addr {IN}:	address.
+ *
+ *  returns
+ *    address to the module.
+ * 
+ */
+
+struct module * lkst_find_module_by_address(unsigned long addr)
+{
+	return (lkst_find_module_by_address_inline(addr));
+}
+EXPORT_SYMBOL(lkst_find_module_by_address);
+
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE */
+
+/*
+ * Function lkst_maxvm_setup
+ * This function gets size of lkst available memory area from kernel parameter.
+ */
+
+static int __init lkst_maxvm_setup(char *line)
+{
+	int size;
+	if (get_option(&line, &size))
+		lkst.available_memory_size = (size_t) size;
+	return 1;
+}
+ 
+__setup("lkst_maxvm=", lkst_maxvm_setup);
+
+
+/*
+ * Function lkst_dummy_vmalloc
+ * This function allocates dummy memory area to gets page directory entry
+ * for LKST using memory area.
+ * Ths area size is set by kernel parameter `lkst_maxvm=`. If omitted,
+ * the size is set to 128M byte. But if 1/10 of physical memory size
+ * is less than 128M byte, 1/10 of physical memory is allocated.
+ * The allocation limit address is stored as lkst.limit_addr.
+ */
+
+__inline__ void lkst_dummy_vmalloc(void)
+{
+	char *buf;
+	long size;
+
+	size = lkst.available_memory_size;
+
+	if (!size) {
+		size = PAGE_SIZE * num_physpages / 10;
+
+		if (size > LKST_AVAILABLE_MEMORY_SIZE)
+			size = LKST_AVAILABLE_MEMORY_SIZE;
+	}
+
+	buf = vmalloc(size);
+
+	if (buf == NULL) {
+		printk(KERN_ERR "LKST warning: Cannot get available memory area(size=%ld) for LKST! Please restart kernel, or cannot allocate memory for LKST.\n", size);
+	} else {
+		lkst.available_memory_size = size;
+		(char *) lkst.limit_addr = (char *) buf + size;
+		printk(KERN_INFO "LKST information: LKST Avaliable memory area is up to an address 0x%p, size is %ld bytes\n", lkst.limit_addr, size);
+		vfree(buf);
+	}
+}
+
+
+struct lkst_hook_info lkst_hook_info_table[LKST_MASKSET_TABLE_LEN_MAX];
+EXPORT_SYMBOL(lkst_hook_info_table);
+
+/* Declaration of hook header */
+#define LKST_ETYPE_DECLARE_HOOKHEADER
+#include <linux/lkst_events.h>
+#undef  LKST_ETYPE_DECLARE_HOOKHEADER
+
+void lkst_trc_hook_init(void)
+{
+	int ret, retall = 0;
+	int i;
+
+	/* Initialize lkst_hook_info_table */
+	for(i=0; i<LKST_MASKSET_TABLE_LEN_MAX; i++){
+		lkst_hook_info_table[i].hook_id = NULL;
+		lkst_hook_info_table[i].phookrec = NULL;
+	}
+
+/* Initialization of hook header */
+#define LKST_ETYPE_INIT_HOOK
+#include <linux/lkst_events.h>
+#undef  LKST_ETYPE_INIT_HOOK
+
+	if (retall) {
+		printk(KERN_ERR "LKST error(hook_init): hook_init failed: %u\n", ret);
+	}
+}
+
+void lkst_trc_hook_cleanup(void)
+{
+	int ret, retall = 0;
+
+/* Cleanup of hook */
+#define LKST_ETYPE_TERMINATE_HOOK
+#include <linux/lkst_events.h>
+#undef  LKST_ETYPE_TERMINATE_HOOK
+
+	if (retall) {
+		printk(KERN_ERR "LKST error(hook_cleanup): hook_cleanup failed: %u\n", ret);
+	}
+}
+EXPORT_SYMBOL(lkst_trc_hook_init);
+EXPORT_SYMBOL(lkst_trc_hook_cleanup);
diff -Naur kernel.orig/linux24/kernel/panic.c kernel/linux24/kernel/panic.c
--- kernel.orig/linux24/kernel/panic.c	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/kernel/panic.c	Fri Jun 28 20:57:45 2002
@@ -15,6 +15,9 @@
 #include <linux/notifier.h>
 #include <linux/dump.h>
 #include <linux/init.h>
+
+#include <linux/lkst.h>
+
 #include <linux/sysrq.h>
 #include <linux/interrupt.h>
 
@@ -60,6 +63,12 @@
 	get_current_regs(&regs);
 #endif
 
+	LKST_HOOK(LKST_ETYPE_O_PANIC,
+		       LKST_ARG32(fmt, 0),
+		       LKST_ARG32(__builtin_return_address(0), 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	bust_spinlocks(1);
 	va_start(args, fmt);
 	vsprintf(buf, fmt, args);
diff -Naur kernel.orig/linux24/kernel/printk.c kernel/linux24/kernel/printk.c
--- kernel.orig/linux24/kernel/printk.c	Sat Dec 22 02:42:04 2001
+++ kernel/linux24/kernel/printk.c	Fri Jun 28 20:57:45 2002
@@ -28,6 +28,8 @@
 
 #include <asm/uaccess.h>
 
+#include <linux/lkst.h>
+
 #ifdef CONFIG_MULTIQUAD
 #define LOG_BUF_LEN	(65536)
 #elif defined(CONFIG_SMP)
@@ -409,6 +411,12 @@
 	static char printk_buf[1024];
 	static int log_level_unknown = 1;
 
+	LKST_HOOK(LKST_ETYPE_O_PRINTK,
+		       LKST_ARG32(fmt, 0),
+		       LKST_ARG32(__builtin_return_address(0), 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	if (oops_in_progress) {
 		/* If a crash is occurring, make sure we can't deadlock */
 		spin_lock_init(&logbuf_lock);
diff -Naur kernel.orig/linux24/kernel/sched.c kernel/linux24/kernel/sched.c
--- kernel.orig/linux24/kernel/sched.c	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/kernel/sched.c	Fri Jun 28 20:57:45 2002
@@ -34,6 +34,8 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 
+#include <linux/lkst.h>
+
 extern void timer_bh(void);
 extern void tqueue_bh(void);
 extern void immediate_bh(void);
@@ -354,6 +356,9 @@
 	unsigned long flags;
 	int success = 0;
 
+	LKST_HOOK_INLINE(LKST_ETYPE_PROCESS_WAKEUP,
+			LKST_ARG32(p,0), LKST_ARG32(synchronous,0),
+			LKST_ARG32(0,0), LKST_ARG32(0,0));
 	/*
 	 * We want the common case fall through straight, thus the goto.
 	 */
@@ -553,7 +558,9 @@
 	struct task_struct *prev, *next, *p;
 	struct list_head *tmp;
 	int this_cpu, c;
-
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+        int lkst_current_counter = current->counter;
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE*/
 
 #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE)
 	if (dump_in_progress) {
@@ -701,6 +708,11 @@
 	 * This just switches the register state and the
 	 * stack.
 	 */
+        LKST_HOOK(LKST_ETYPE_PROCESS_CONTEXTSWITCH,
+		       LKST_ARG32(prev,0), LKST_ARG32(next,0),
+		       LKST_ARG32(prev->state,lkst_current_counter),
+		       LKST_ARG32(0,0)); 
+// TODO : add SYNC events
 	switch_to(prev, next, prev);
 	__schedule_tail(prev);
 
diff -Naur kernel.orig/linux24/kernel/signal.c kernel/linux24/kernel/signal.c
--- kernel.orig/linux24/kernel/signal.c	Thu Nov 22 09:26:27 2001
+++ kernel/linux24/kernel/signal.c	Fri Jun 28 20:57:45 2002
@@ -16,6 +16,8 @@
 
 #include <asm/uaccess.h>
 
+#include <linux/lkst.h>
+
 /*
  * SLAB caches for signal bits.
  */
@@ -511,6 +513,11 @@
 printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
 #endif
 
+	LKST_HOOK(LKST_ETYPE_PROCESS_SIGSEND,
+			LKST_ARG32(sig,0), LKST_ARG32(t,0),
+			LKST_ARG32(info,0),
+			LKST_ARG32(0,0));
+
 	ret = -EINVAL;
 	if (sig < 0 || sig > _NSIG)
 		goto out_nolock;
diff -Naur kernel.orig/linux24/kernel/softirq.c kernel/linux24/kernel/softirq.c
--- kernel.orig/linux24/kernel/softirq.c	Thu Nov  1 03:26:02 2001
+++ kernel/linux24/kernel/softirq.c	Fri Jun 28 20:57:45 2002
@@ -17,6 +17,8 @@
 #include <linux/init.h>
 #include <linux/tqueue.h>
 
+#include <linux/lkst.h>
+
 /*
    - No shared variables, all the data are CPU local.
    - If a softirq needs serialization, let it serialize itself
@@ -192,6 +194,9 @@
 			if (!atomic_read(&t->count)) {
 				if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
 					BUG();
+	LKST_HOOK(LKST_ETYPE_INT_TASKLET_ENTRY,
+		LKST_ARG32(t->func,0), LKST_ARG32(0,0),
+		LKST_ARG32(0,0), LKST_ARG32(0,0));
 				t->func(t->data);
 				tasklet_unlock(t);
 				continue;
@@ -226,6 +231,9 @@
 			if (!atomic_read(&t->count)) {
 				if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
 					BUG();
+       LKST_HOOK(LKST_ETYPE_INT_TASKLETHI_ENTRY,
+		LKST_ARG32(t->func,0), LKST_ARG32(0,0),
+		LKST_ARG32(0,0), LKST_ARG32(0,0));
 				t->func(t->data);
 				tasklet_unlock(t);
 				continue;
@@ -297,7 +305,16 @@
 		goto resched_unlock;
 
 	if (bh_base[nr])
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+        {
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE*/
+		LKST_HOOK(LKST_ETYPE_INT_BH_ENTRY,
+			LKST_ARG32(nr,0), LKST_ARG32(bh_base[nr],0),
+			LKST_ARG32(0,0), LKST_ARG32(0,0));
 		bh_base[nr]();
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+        }
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE*/
 
 	hardirq_endlock(cpu);
 	spin_unlock(&global_bh_lock);
diff -Naur kernel.orig/linux24/kernel/sys.c kernel/linux24/kernel/sys.c
--- kernel.orig/linux24/kernel/sys.c	Fri Jun 28 21:03:30 2002
+++ kernel/linux24/kernel/sys.c	Fri Jun 28 20:57:45 2002
@@ -21,6 +21,8 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
+#include <linux/lkst.h>
+
 /*
  * this is where the system-wide overflow UID and GID are defined, for
  * architectures that now have 32-bit UID/GID but didn't in the past
@@ -448,6 +450,9 @@
 	current->fsgid = new_egid;
 	current->egid = new_egid;
 	current->gid = new_rgid;
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_GID,
+		       LKST_ARG32(new_rgid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return 0;
 }
 
@@ -480,6 +485,9 @@
 	}
 	else
 		return -EPERM;
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_GID,
+		       LKST_ARG32(current->gid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return 0;
 }
   
@@ -553,6 +561,9 @@
 	current->uid = new_ruid;
 	current->user = new_user;
 	free_uid(old_user);
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_UID,
+		       LKST_ARG32(new_ruid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return 0;
 }
 
@@ -713,7 +724,9 @@
 	if (!(retval = put_user(current->uid, ruid)) &&
 	    !(retval = put_user(current->euid, euid)))
 		retval = put_user(current->suid, suid);
-
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_UID,
+		       LKST_ARG32(*ruid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return retval;
 }
 
@@ -746,6 +759,9 @@
 		current->gid = rgid;
 	if (sgid != (gid_t) -1)
 		current->sgid = sgid;
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_GID,
+		       LKST_ARG32(current->gid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return 0;
 }
 
@@ -756,7 +772,9 @@
 	if (!(retval = put_user(current->gid, rgid)) &&
 	    !(retval = put_user(current->egid, egid)))
 		retval = put_user(current->sgid, sgid);
-
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_GID,
+		       LKST_ARG32(current->gid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return retval;
 }
 
@@ -902,6 +920,9 @@
 ok_pgid:
 	p->pgrp = pgid;
 	err = 0;
+	LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_PGID,
+		       LKST_ARG32(p->pid, 0), LKST_ARG32(p->pgrp, 0),
+		       LKST_ARG32(p, 0), LKST_ARG32(p->leader, 0)); 
 out:
 	/* All paths lead to here, thus we are safe. -DaveM */
 	read_unlock(&tasklist_lock);
@@ -911,6 +932,11 @@
 asmlinkage long sys_getpgid(pid_t pid)
 {
 	if (!pid) {
+		LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_PGID,
+			       LKST_ARG32(current->pid, 0),
+			       LKST_ARG32(current->pgrp, 0),
+			       LKST_ARG32(current, 0),
+			       LKST_ARG32(current->leader, 0)); 
 		return current->pgrp;
 	} else {
 		int retval;
@@ -922,6 +948,14 @@
 		retval = -ESRCH;
 		if (p)
 			retval = p->pgrp;
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+		if (p) 
+			LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_PGID,
+				       LKST_ARG32(p->pid, 0),
+				       LKST_ARG32(p->pgrp, 0),
+				       LKST_ARG32(p, 0),
+				       LKST_ARG32(p->leader, 0));
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE*/
 		read_unlock(&tasklist_lock);
 		return retval;
 	}
@@ -930,6 +964,11 @@
 asmlinkage long sys_getpgrp(void)
 {
 	/* SMP - assuming writes are word atomic this is fine */
+	LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_PGID,
+		       LKST_ARG32(current->pid, 0),
+		       LKST_ARG32(current->pgrp, 0),
+		       LKST_ARG32(current, 0),
+		       LKST_ARG32(current->leader, 0));
 	return current->pgrp;
 }
 
@@ -970,6 +1009,11 @@
 	err = current->pgrp;
 out:
 	read_unlock(&tasklist_lock);
+	LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_PGID,
+		       LKST_ARG32(current->pid, 0),
+		       LKST_ARG32(current->pgrp, 0),
+		       LKST_ARG32(current, 0),
+		       LKST_ARG32(current->leader, 0));
 	return err;
 }
 
diff -Naur kernel.orig/linux24/kernel/time.c kernel/linux24/kernel/time.c
--- kernel.orig/linux24/kernel/time.c	Sat Dec 22 02:42:04 2001
+++ kernel/linux24/kernel/time.c	Fri Jun 28 20:57:45 2002
@@ -30,6 +30,10 @@
 
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+#include <linux/lkst.h>
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE*/
+
 /* 
  * The timezone where the local system is located.  Used as a default by some
  * programs who obtain this value by using gettimeofday.
@@ -182,6 +186,10 @@
 		 */
 		do_settimeofday(tv);
 	}
+#if defined(CONFIG_DEBUG_KERNEL_STATE_TRACE) ||  defined(CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE)
+	if (!firsttime)
+		lkst_time_set(1);
+#endif /* CONFIG_DEBUG_KERNEL_STATE_TRACE || CONFIG_DEBUG_KERNEL_STATE_TRACE_MODULE*/
 	return 0;
 }
 
diff -Naur kernel.orig/linux24/kernel/timer.c kernel/linux24/kernel/timer.c
--- kernel.orig/linux24/kernel/timer.c	Tue Oct  9 02:41:41 2001
+++ kernel/linux24/kernel/timer.c	Fri Jun 28 20:57:45 2002
@@ -25,6 +25,8 @@
 
 #include <asm/uaccess.h>
 
+#include <linux/lkst.h>
+
 /*
  * Timekeeping variables
  */
@@ -181,6 +183,11 @@
 	if (timer_pending(timer))
 		goto bug;
 	internal_add_timer(timer);
+        LKST_HOOK(LKST_ETYPE_TIMER_ADD,
+		       LKST_ARG32(timer, 0),
+		       LKST_ARG32(timer->expires, 0),
+		       LKST_ARG32(timer->function, 0),
+		       LKST_ARG32(timer->data, 0)); 
 	spin_unlock_irqrestore(&timerlist_lock, flags);
 	return;
 bug:
@@ -206,6 +213,11 @@
 	timer->expires = expires;
 	ret = detach_timer(timer);
 	internal_add_timer(timer);
+        LKST_HOOK(LKST_ETYPE_TIMER_MOD,
+		       LKST_ARG32(timer, 0),
+		       LKST_ARG32(timer->expires, 0),
+		       LKST_ARG32(timer->function, 0),
+		       LKST_ARG32(timer->data, 0)); 
 	spin_unlock_irqrestore(&timerlist_lock, flags);
 	return ret;
 }
@@ -216,6 +228,11 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&timerlist_lock, flags);
+        LKST_HOOK(LKST_ETYPE_TIMER_DEL,
+		       LKST_ARG32(timer, 0),
+		       LKST_ARG32(timer->expires, 0),
+		       LKST_ARG32(timer->function, 0),
+		       LKST_ARG32(timer->data, 0)); 
 	ret = detach_timer(timer);
 	timer->list.next = timer->list.prev = NULL;
 	spin_unlock_irqrestore(&timerlist_lock, flags);
@@ -240,6 +257,11 @@
 {
 	int ret = 0;
 
+        LKST_HOOK(LKST_ETYPE_TIMER_DEL_SYNC,
+		       LKST_ARG32(timer, 0),
+		       LKST_ARG32(timer->expires, 0),
+		       LKST_ARG32(timer->function, 0),
+		       LKST_ARG32(timer->data, 0)); 
 	for (;;) {
 		unsigned long flags;
 		int running;
@@ -313,6 +335,12 @@
 			timer_enter(timer);
 			spin_unlock_irq(&timerlist_lock);
 			fn(data);
+
+			LKST_HOOK_INLINE(LKST_ETYPE_TIMER_RUN,
+				       LKST_ARG32(fn, 0),
+				       LKST_ARG32(data, 0),
+				       LKST_ARG32(0, 0),
+				       LKST_ARG32(0, 0));
 			spin_lock_irq(&timerlist_lock);
 			timer_exit();
 			goto repeat;
@@ -771,6 +799,9 @@
 asmlinkage long sys_getuid(void)
 {
 	/* Only we change this so SMP safe */
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_UID,
+		       LKST_ARG32(current->uid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return current->uid;
 }
 
@@ -783,7 +814,11 @@
 asmlinkage long sys_getgid(void)
 {
 	/* Only we change this so SMP safe */
+        LKST_HOOK_INLINE(LKST_ETYPE_LKST_SYNC_GID,
+		       LKST_ARG32(current->gid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return current->gid;
+
 }
 
 asmlinkage long sys_getegid(void)
@@ -797,6 +832,9 @@
 /* Thread ID - the internal kernel "pid" */
 asmlinkage long sys_gettid(void)
 {
+        LKST_HOOK(LKST_ETYPE_LKST_SYNC_TID,
+		       LKST_ARG32(current->pid, 0), LKST_ARG32(0, 0),
+		       LKST_ARG32(current, 0), LKST_ARG32(0, 0)); 
 	return current->pid;
 }
 
diff -Naur kernel.orig/linux24/mm/filemap.c kernel/linux24/mm/filemap.c
--- kernel.orig/linux24/mm/filemap.c	Sat Dec 22 02:42:04 2001
+++ kernel/linux24/mm/filemap.c	Fri Jun 28 20:57:45 2002
@@ -31,6 +31,8 @@
 
 #include <linux/highmem.h>
 
+#include <linux/lkst.h>
+
 /*
  * Shared mappings implemented 30.11.1994. It's not fully working yet,
  * though.
@@ -782,6 +784,12 @@
 	struct task_struct *tsk = current;
 	DECLARE_WAITQUEUE(wait, tsk);
 
+	LKST_HOOK(LKST_ETYPE_MEM_WAIT_PAGE,
+		       LKST_ARG32(page, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	add_wait_queue(&page->wait, &wait);
 	do {
 		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
diff -Naur kernel.orig/linux24/mm/memory.c kernel/linux24/mm/memory.c
--- kernel.orig/linux24/mm/memory.c	Sat Dec 22 02:42:05 2001
+++ kernel/linux24/mm/memory.c	Fri Jun 28 20:57:45 2002
@@ -49,6 +49,8 @@
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
 
+#include <linux/lkst.h>
+
 unsigned long max_mapnr;
 unsigned long num_physpages;
 void * high_memory;
@@ -946,6 +948,12 @@
 		goto no_mem;
 	copy_cow_page(old_page,new_page,address);
 
+	LKST_HOOK(LKST_ETYPE_MEM_DO_WPPAGE,
+		       LKST_ARG32(new_page, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	/*
 	 * Re-check the pte - we dropped the lock
 	 */
@@ -1149,6 +1157,13 @@
 	/* No need to invalidate - it was non-present before */
 	update_mmu_cache(vma, address, pte);
 	spin_unlock(&mm->page_table_lock);
+
+	LKST_HOOK(LKST_ETYPE_MEM_SWAPIN,
+		       LKST_ARG32(page, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	return ret;
 }
 
@@ -1274,6 +1289,13 @@
 	/* no need to invalidate: a not-present page shouldn't be cached */
 	update_mmu_cache(vma, address, entry);
 	spin_unlock(&mm->page_table_lock);
+
+	LKST_HOOK(LKST_ETYPE_MEM_DO_NOPAGE,
+		       LKST_ARG32(new_page, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	return 2;	/* Major fault */
 }
 
diff -Naur kernel.orig/linux24/mm/page_alloc.c kernel/linux24/mm/page_alloc.c
--- kernel.orig/linux24/mm/page_alloc.c	Tue Nov 20 09:35:40 2001
+++ kernel/linux24/mm/page_alloc.c	Fri Jun 28 20:57:45 2002
@@ -19,6 +19,8 @@
 #include <linux/slab.h>
 #include <linux/compiler.h>
 
+#include <linux/lkst.h>
+
 int nr_swap_pages;
 int nr_active_pages;
 int nr_inactive_pages;
@@ -406,11 +408,19 @@
 unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
 {
 	struct page * page;
+	unsigned long paddr;
 
 	page = alloc_pages(gfp_mask, order);
 	if (!page)
 		return 0;
-	return (unsigned long) page_address(page);
+	paddr = (unsigned long) page_address(page);
+	LKST_HOOK(LKST_ETYPE_MEM_GET_FREEPAGE,
+		       LKST_ARG32(paddr, 0),
+		       LKST_ARG32(gfp_mask, 0),
+		       LKST_ARG32(order, 0),
+		       LKST_ARG32(__builtin_return_address(0), 0));
+
+	return paddr;
 }
 
 unsigned long get_zeroed_page(unsigned int gfp_mask)
@@ -421,6 +431,11 @@
 	if (page) {
 		void *address = page_address(page);
 		clear_page(address);
+		LKST_HOOK(LKST_ETYPE_MEM_GET_ZEROPAGE,
+			       LKST_ARG32(address, 0),
+			       LKST_ARG32(gfp_mask, 0),
+			       LKST_ARG32(__builtin_return_address(0), 0),
+			       LKST_ARG32(0, 0));
 		return (unsigned long) address;
 	}
 	return 0;
@@ -443,8 +458,14 @@
 
 void free_pages(unsigned long addr, unsigned int order)
 {
-	if (addr != 0)
+	if (addr != 0) {
+		LKST_HOOK(LKST_ETYPE_MEM_FREEPAGE,
+			       LKST_ARG32(addr, 0), 
+			       LKST_ARG32(order, 0),
+			       LKST_ARG32(__builtin_return_address(0), 0),
+			       LKST_ARG32(0, 0));
 		__free_pages(virt_to_page(addr), order);
+	}
 }
 
 /*
diff -Naur kernel.orig/linux24/mm/slab.c kernel/linux24/mm/slab.c
--- kernel.orig/linux24/mm/slab.c	Sat Dec 22 02:42:05 2001
+++ kernel/linux24/mm/slab.c	Fri Jun 28 20:57:45 2002
@@ -75,6 +75,8 @@
 #include	<linux/compiler.h>
 #include	<asm/uaccess.h>
 
+#include <linux/lkst.h>
+
 /*
  * DEBUG	- 1 for kmem_cache_create() to honour; SLAB_DEBUG_INITIAL,
  *		  SLAB_RED_ZONE & SLAB_POISON.
@@ -822,6 +824,13 @@
 	list_add(&cachep->next, &cache_chain);
 	up(&cache_chain_sem);
 opps:
+
+	LKST_HOOK(LKST_ETYPE_MEM_CACHE_CREATE,
+		       LKST_ARG32(name, 0),
+		       LKST_ARG32(size, 0),
+		       LKST_ARG32(cachep, 0),
+		       LKST_ARG32(0, 0));
+
 	return cachep;
 }
 
@@ -1508,7 +1517,16 @@
  */
 void * kmem_cache_alloc (kmem_cache_t *cachep, int flags)
 {
-	return __kmem_cache_alloc(cachep, flags);
+	void* objp;
+	objp = __kmem_cache_alloc(cachep, flags);
+
+	LKST_HOOK(LKST_ETYPE_MEM_CACHE_ALLOC,
+		       LKST_ARG32(cachep, 0),
+		       LKST_ARG32(flags, 0),
+		       LKST_ARG32(objp, 0),
+		       LKST_ARG32(__builtin_return_address(0), 0));
+
+	return objp;
 }
 
 /**
@@ -1534,13 +1552,23 @@
  */
 void * kmalloc (size_t size, int flags)
 {
+	void* objp;
 	cache_sizes_t *csizep = cache_sizes;
 
 	for (; csizep->cs_size; csizep++) {
 		if (size > csizep->cs_size)
 			continue;
-		return __kmem_cache_alloc(flags & GFP_DMA ?
+
+		objp = __kmem_cache_alloc(flags & GFP_DMA ?
 			 csizep->cs_dmacachep : csizep->cs_cachep, flags);
+
+		LKST_HOOK(LKST_ETYPE_MEM_MALLOC,
+			       LKST_ARG32(size, 0),
+			       LKST_ARG32(flags, 0),
+			       LKST_ARG32(objp, 0),
+			       LKST_ARG32(__builtin_return_address(0), 0));
+
+		return objp;
 	}
 	return NULL;
 }
@@ -1556,6 +1584,13 @@
 void kmem_cache_free (kmem_cache_t *cachep, void *objp)
 {
 	unsigned long flags;
+
+	LKST_HOOK(LKST_ETYPE_MEM_CACHE_FREE,
+		       LKST_ARG32(cachep, 0),
+		       LKST_ARG32(objp, 0),
+		       LKST_ARG32(__builtin_return_address(0), 0),
+		       LKST_ARG32(0, 0));
+
 #if DEBUG
 	CHECK_PAGE(virt_to_page(objp));
 	if (cachep != GET_PAGE_CACHE(virt_to_page(objp)))
@@ -1579,6 +1614,12 @@
 	kmem_cache_t *c;
 	unsigned long flags;
 
+	LKST_HOOK(LKST_ETYPE_MEM_FREE,
+		       LKST_ARG32(objp, 0),
+		       LKST_ARG32(__builtin_return_address(0), 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	if (!objp)
 		return;
 	local_irq_save(flags);
diff -Naur kernel.orig/linux24/mm/vmalloc.c kernel/linux24/mm/vmalloc.c
--- kernel.orig/linux24/mm/vmalloc.c	Sat Dec 22 02:42:05 2001
+++ kernel/linux24/mm/vmalloc.c	Fri Jun 28 20:57:45 2002
@@ -16,6 +16,8 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 
+#include <linux/lkst.h>
+
 rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
 struct vm_struct * vmlist;
 
@@ -207,6 +209,13 @@
 
 	if (!addr)
 		return;
+
+	LKST_HOOK(LKST_ETYPE_MEM_VFREE,
+		       LKST_ARG32(addr, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0),
+		       LKST_ARG32(0, 0));
+
 	if ((PAGE_SIZE-1) & (unsigned long) addr) {
 		printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr);
 		return;
diff -Naur kernel.orig/linux24/mm/vmscan.c kernel/linux24/mm/vmscan.c
--- kernel.orig/linux24/mm/vmscan.c	Sat Dec 22 02:42:05 2001
+++ kernel/linux24/mm/vmscan.c	Fri Jun 28 20:57:45 2002
@@ -24,6 +24,8 @@
 
 #include <asm/pgalloc.h>
 
+#include <linux/lkst.h>
+
 /*
  * The "priority" of VM scanning is how much of the queues we
  * will scan in one go. A value of 6 for DEF_PRIORITY implies
@@ -92,6 +94,13 @@
 		{
 			int freeable = page_count(page) - !!page->buffers <= 2;
 			page_cache_release(page);
+
+			LKST_HOOK_INLINE(LKST_ETYPE_MEM_SWAPOUT,
+				       LKST_ARG32(page, 0),
+				       LKST_ARG32(0, 0),
+				       LKST_ARG32(0, 0),
+				       LKST_ARG32(0, 0));
+
 			return freeable;
 		}
 	}
diff -Naur kernel.orig/linux24/net/core/dev.c kernel/linux24/net/core/dev.c
--- kernel.orig/linux24/net/core/dev.c	Thu Nov  8 07:39:36 2001
+++ kernel/linux24/net/core/dev.c	Fri Jun 28 20:57:45 2002
@@ -106,6 +106,7 @@
 #ifdef CONFIG_PLIP
 extern int plip_init(void);
 #endif
+#include <linux/lkst.h>
 
 
 /* This define, if set, will randomly drop a packet when congestion
@@ -977,6 +978,11 @@
 	struct net_device *dev = skb->dev;
 	struct Qdisc  *q;
 
+        LKST_HOOK(LKST_ETYPE_NET_PKTSEND,
+			LKST_ARG32(skb,0), LKST_ARG32(0,0),
+			LKST_ARG32(0,0),
+			LKST_ARG32(0,0)); 
+
 	if (skb_shinfo(skb)->frag_list &&
 	    !(dev->features&NETIF_F_FRAGLIST) &&
 	    skb_linearize(skb, GFP_ATOMIC) != 0) {
@@ -1217,6 +1223,10 @@
 	struct softnet_data *queue;
 	unsigned long flags;
 
+        LKST_HOOK(LKST_ETYPE_NET_PKTRECV,
+			LKST_ARG32(skb,0), LKST_ARG32(0,0),
+			LKST_ARG32(0,0),
+			LKST_ARG32(0,0)); 
 	if (skb->stamp.tv_sec == 0)
 		get_fast_time(&skb->stamp);
 
@@ -1326,6 +1336,11 @@
 {
 	int cpu = smp_processor_id();
 
+        LKST_HOOK(LKST_ETYPE_NET_PKTSENDI,
+			LKST_ARG32(h,0), LKST_ARG32(0,0),
+			LKST_ARG32(0,0),
+			LKST_ARG32(0,0)); 
+
 	if (softnet_data[cpu].completion_queue) {
 		struct sk_buff *clist;
 
@@ -1425,6 +1440,11 @@
 
 	br_read_lock(BR_NETPROTO_LOCK);
 
+        LKST_HOOK(LKST_ETYPE_NET_PKTRECVI,
+			LKST_ARG32(h,0), LKST_ARG32(0,0),
+			LKST_ARG32(0,0),
+			LKST_ARG32(0,0)); 
+
 	for (;;) {
 		struct sk_buff *skb;
 		struct net_device *rx_dev;
diff -Naur kernel.orig/linux24/net/socket.c kernel/linux24/net/socket.c
--- kernel.orig/linux24/net/socket.c	Sat Dec 22 02:42:06 2001
+++ kernel/linux24/net/socket.c	Fri Jun 28 20:57:45 2002
@@ -84,6 +84,7 @@
 #include <net/sock.h>
 #include <net/scm.h>
 #include <linux/netfilter.h>
+#include <linux/lkst.h>
 
 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
 static loff_t sock_lseek(struct file *file, loff_t offset, int whence);
@@ -1548,6 +1549,11 @@
 	unsigned long a0,a1;
 	int err;
 
+        LKST_HOOK(LKST_ETYPE_NET_SOCKETIF,
+			LKST_ARG32(call,0), LKST_ARG32(args,0),
+			LKST_ARG32(0,0),
+			LKST_ARG32(0,0)); 
+
 	if(call<1||call>SYS_RECVMSG)
 		return -EINVAL;
 
