#include <linux/sched.h>
#include <linux/module.h>
+#include <linux/kconfig.h>
#include <linux/completion.h>
#include <ksyms/ksyms.h>
#include <kprobe/swap_ktd.h>
-#include <kprobe/swap_kprobes.h>
#include <master/swap_initializer.h>
#include "task_ctx.h"
EXPORT_SYMBOL_GPL(taskctx_run);
-static int sig_pre_handler(struct kprobe *p, struct pt_regs *regs)
+static void sig_handler(void)
{
struct call_task *call = call_get(current);
call->func(call->data);
complete(&call->comp1);
}
+}
+
+
+#ifdef CONFIG_SWAP_HOOK_SIGNAL
+# include <swap/hook_signal.h>
+void hook_handler(struct ksignal *ksig)
+{
+ sig_handler();
+}
+
+struct hook_signal hook_signal = {
+ .owner = THIS_MODULE,
+ .hook = hook_handler,
+};
+
+static int signal_reg(void)
+{
+ int ret = hook_signal_reg(&hook_signal);
+ if (ret)
+ pr_err("Cannot register hook_signal, ret=%d\n", ret);
+
+ return ret;
+}
+
+static void signal_unreg(void)
+{
+ hook_signal_unreg(&hook_signal);
+}
+static int signal_once(void)
+{
return 0;
}
+#else /* !CONFIG_SWAP_HOOK_SIGNAL */
+# include <kprobe/swap_kprobes.h>
+
+static int sig_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ sig_handler();
+
+ return 0;
+}
static struct kprobe sig_kprobe = {
.pre_handler = sig_pre_handler,
};
-static int register_signal(void)
+static int signal_reg(void)
{
- int ret = 0;
-
- ret = swap_register_kprobe(&sig_kprobe);
+ int ret = swap_register_kprobe(&sig_kprobe);
if (ret)
pr_err("register sig_kprobe ret=%d\n", ret);
return ret;
}
-static void unregister_sig(void)
+static void signal_unreg(void)
{
swap_unregister_kprobe(&sig_kprobe);
}
+static int signal_once(void)
+{
+ const char *sym;
+
+ sym = "signal_wake_up_state";
+ swap_signal_wake_up_state = (void *)swap_ksyms(sym);
+ if (swap_signal_wake_up_state == NULL)
+ goto not_found;
+
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+ sym = "get_signal";
+# else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) */
+ sym = "get_signal_to_deliver";
+# endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) */
+ sig_kprobe.addr = swap_ksyms(sym);
+ if (sig_kprobe.addr == 0)
+ goto not_found;
+
+ return 0;
+
+not_found:
+ printk("Cannot find address for '%s'!\n", sym);
+ return -ESRCH;
+}
+#endif /* CONFIG_SWAP_HOOK_SIGNAL */
+
static int use_cnt = 0;
static DEFINE_MUTEX(use_lock);
mutex_lock(&use_lock);
if (use_cnt == 0) {
- ret = register_signal();
+ ret = signal_reg();
if (ret)
goto unlock;
}
--use_cnt;
if (use_cnt == 0)
- unregister_sig();
+ signal_unreg();
unlock:
mutex_unlock(&use_lock);
static int taskctx_once(void)
{
- const char *sym;
-
- sym = "signal_wake_up_state";
- swap_signal_wake_up_state = (void *)swap_ksyms(sym);
- if (swap_signal_wake_up_state == NULL)
- goto not_found;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
- sym = "get_signal";
-#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) */
- sym = "get_signal_to_deliver";
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) */
- sig_kprobe.addr = swap_ksyms(sym);
- if (sig_kprobe.addr == 0)
- goto not_found;
-
- return 0;
-
-not_found:
- printk("Cannot find address for '%s'!\n", sym);
- return -ESRCH;
+ return signal_once();
}
static int taskctx_init(void)