/*
 * RAS Instrumentation hooks.
 *
 * Most of these hooks are for Linux Trace Toolkit. They may also be
 * used by any other tool.
 * 
 * Author: Vamsi Krishna S. <vamsi_krishna@in.ibm.com>
 */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/hook.h>
#include <linux/rashooks.h>
#include <linux/ptrace.h>

DECLARE_RAS_HOOK(ipc_call_hook);
DECLARE_RAS_HOOK(ipc_msg_create_hook);
DECLARE_RAS_HOOK(ipc_sem_create_hook);
DECLARE_RAS_HOOK(ipc_shm_create_hook);

DECLARE_RAS_HOOK(irq_entry_hook);
DECLARE_RAS_HOOK(irq_exit_hook);

DECLARE_RAS_HOOK(kernel_timer_hook);

DECLARE_RAS_HOOK(kthread_hook);
DECLARE_RAS_HOOK(exec_hook);
DECLARE_RAS_HOOK(fork_hook);
DECLARE_RAS_HOOK(process_exit_hook);
DECLARE_RAS_HOOK(process_wait_hook);
DECLARE_RAS_HOOK(process_wakeup_hook);
DECLARE_RAS_HOOK(sched_switch_hook);
DECLARE_RAS_HOOK(sched_dispatch_hook);
DECLARE_RAS_HOOK(signal_hook);

DECLARE_RAS_HOOK(open_hook);
DECLARE_RAS_HOOK(close_hook);
DECLARE_RAS_HOOK(llseek_hook);
DECLARE_RAS_HOOK(lseek_hook);
DECLARE_RAS_HOOK(ioctl_hook);
DECLARE_RAS_HOOK(poll_hook);
DECLARE_RAS_HOOK(select_hook);
DECLARE_RAS_HOOK(read_hook);
DECLARE_RAS_HOOK(write_hook);
DECLARE_RAS_HOOK(buf_wait_end_hook);
DECLARE_RAS_HOOK(buf_wait_start_hook);


DECLARE_RAS_HOOK(mmap_hook);
DECLARE_RAS_HOOK(mm_page_alloc_hook);
DECLARE_RAS_HOOK(mm_page_free_hook);
DECLARE_RAS_HOOK(mm_swap_in_hook);
DECLARE_RAS_HOOK(mm_swap_out_hook);
DECLARE_RAS_HOOK(page_wait_end_hook);
DECLARE_RAS_HOOK(page_wait_start_hook);

DECLARE_RAS_HOOK(net_pkt_in_hook);
DECLARE_RAS_HOOK(net_pkt_out_hook);

DECLARE_RAS_HOOK(sk_call_hook);
DECLARE_RAS_HOOK(sk_create_hook);
DECLARE_RAS_HOOK(sk_receive_hook);
DECLARE_RAS_HOOK(sk_send_hook);

DECLARE_RAS_HOOK(softirq_hook);
DECLARE_RAS_HOOK(tasklet_action_hook);
DECLARE_RAS_HOOK(tasklet_hi_action_hook);
DECLARE_RAS_HOOK(bh_hook);

DECLARE_RAS_HOOK(timer_expired_hook);
DECLARE_RAS_HOOK(setitimer_hook);
DECLARE_RAS_HOOK(settimeout_hook);

DECLARE_RAS_HOOK(trap_entry_hook);
DECLARE_RAS_HOOK(trap_exit_hook);

DECLARE_RAS_HOOK(timer_hook);

#ifdef CONFIG_RAS_SYSCALL_HOOK
DECLARE_RAS_HOOK(pre_syscall_hook);
DECLARE_RAS_HOOK(post_syscall_hook);
/* 
 * as syscalls are very sensitive, we have extra steps to enable 
 * pre/post syscall hooks. Besides registering and arming hooks
 * one has to call enable/disable_pre/post_syscall_hook().
 */
int pre_syscall_enabled;
int post_syscall_enabled;

void enable_pre_syscall(void)
{
	pre_syscall_enabled = 1;
}
EXPORT_SYMBOL(enable_pre_syscall);

void enable_post_syscall(void)
{
	post_syscall_enabled = 1;
}
EXPORT_SYMBOL(enable_post_syscall);

void disable_pre_syscall(void)
{
	pre_syscall_enabled = 0;
}
EXPORT_SYMBOL(disable_pre_syscall);

void disable_post_syscall(void)
{
	post_syscall_enabled = 0;
}
EXPORT_SYMBOL(disable_post_syscall);

asmlinkage void pre_syscall(struct pt_regs * regs)
{
	RAS_HOOK(pre_syscall_hook, regs);
}

asmlinkage void post_syscall(void)
{
	RAS_HOOK(post_syscall_hook);
}
#endif /* CONFIG_RAS_SYSCALL_HOOK */
