2 * ktap.c - ktapvm kernel module main entry
4 * This file is part of ktap by Jovi Zhangwei.
6 * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
8 * ktap is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
12 * ktap is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23 * this file is the first file to be compile, add CONFIG_ checking in here.
24 * See Requirements in doc/introduction.txt
27 #include <linux/version.h>
28 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
29 #error "Currently ktap don't support kernel older than 3.1"
32 #if !CONFIG_EVENT_TRACING
33 #error "Please enable CONFIG_EVENT_TRACING before compile ktap"
36 #if !CONFIG_PERF_EVENTS
37 #error "Please enable CONFIG_PERF_EVENTS before compile ktap"
40 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
42 #include <linux/module.h>
43 #include <linux/errno.h>
44 #include <linux/file.h>
45 #include <linux/slab.h>
46 #include <linux/fcntl.h>
47 #include <linux/sched.h>
48 #include <linux/poll.h>
49 #include <linux/anon_inodes.h>
50 #include <linux/debugfs.h>
51 #include <linux/vmalloc.h>
52 #include "../include/ktap_types.h"
57 static int load_trunk(struct ktap_parm *parm, unsigned long **buff)
60 unsigned long *vmstart;
62 vmstart = vmalloc(parm->trunk_len);
66 ret = copy_from_user(vmstart, (void __user *)parm->trunk,
77 static struct dentry *kp_dir_dentry;
80 static int ktap_main(struct file *file, ktap_parm *parm)
82 unsigned long *buff = NULL;
85 int start_time, delta_time;
88 start_time = gettimeofday_us();
90 ks = kp_newstate(parm, kp_dir_dentry);
94 file->private_data = ks;
96 ret = load_trunk(parm, &buff);
98 pr_err("cannot load file\n");
102 cl = kp_load(ks, (unsigned char *)buff);
107 /* optimize bytecode before excuting */
108 kp_optimize_code(ks, 0, cl->p);
110 delta_time = gettimeofday_us() - start_time;
111 kp_verbose_printf(ks, "booting time: %d (us)\n", delta_time);
112 kp_call(ks, ks->top - 1, 0);
120 static void print_version(void)
124 static long ktap_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
130 case KTAP_CMD_IOC_VERSION:
133 case KTAP_CMD_IOC_RUN:
134 ret = copy_from_user(&parm, (void __user *)arg,
139 return ktap_main(file, &parm);
147 static const struct file_operations ktap_fops = {
149 .unlocked_ioctl = ktap_ioctl,
152 static long ktapvm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
155 struct file *new_file;
157 new_fd = get_unused_fd();
161 new_file = anon_inode_getfile("[ktap]", &ktap_fops, NULL, O_RDWR);
162 if (IS_ERR(new_file)) {
163 err = PTR_ERR(new_file);
164 put_unused_fd(new_fd);
168 file->private_data = NULL;
169 fd_install(new_fd, new_file);
173 static const struct file_operations ktapvm_fops = {
174 .owner = THIS_MODULE,
175 .unlocked_ioctl = ktapvm_ioctl,
178 static int __init init_ktap(void)
180 struct dentry *ktapvm_dentry;
182 kp_dir_dentry = debugfs_create_dir("ktap", NULL);
183 if (!kp_dir_dentry) {
184 pr_err("ktap: debugfs_create_dir failed\n");
188 ktapvm_dentry = debugfs_create_file("ktapvm", 0444, kp_dir_dentry, NULL,
191 if (!ktapvm_dentry) {
192 pr_err("ktapvm: cannot create ktapvm file\n");
193 debugfs_remove_recursive(kp_dir_dentry);
197 kp_init_exit_instruction();
202 static void __exit exit_ktap(void)
204 debugfs_remove_recursive(kp_dir_dentry);
207 module_init(init_ktap);
208 module_exit(exit_ktap);
210 MODULE_AUTHOR("Jovi Zhangwei <jovi.zhangwei@gmail.com>");
211 MODULE_DESCRIPTION("ktap");
212 MODULE_LICENSE("GPL");
214 int kp_max_exec_count = 10000;
215 module_param_named(max_exec_count, kp_max_exec_count, int, S_IRUGO | S_IWUSR);
216 MODULE_PARM_DESC(max_exec_count, "non-mainthread max instruction execution count");