Merge tag 'v3.14.25' into backport/v3.14.24-ltsi-rc1+v3.14.25/snapshot-merge.wip
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / ktap / runtime / ktap.c
1 /*
2  * ktap.c - ktapvm kernel module main entry
3  *
4  * This file is part of ktap by Jovi Zhangwei.
5  *
6  * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
7  *
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.
11  *
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
15  * more details.
16  *
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.
20  */
21
22 /*
23  * this file is the first file to be compile, add CONFIG_ checking in here.
24  * See Requirements in doc/introduction.txt
25  */
26
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"
30 #endif
31
32 #if !CONFIG_EVENT_TRACING
33 #error "Please enable CONFIG_EVENT_TRACING before compile ktap"
34 #endif
35
36 #if !CONFIG_PERF_EVENTS
37 #error "Please enable CONFIG_PERF_EVENTS before compile ktap"
38 #endif
39
40 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
41
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"
53 #include "ktap.h"
54 #include "kp_load.h"
55 #include "kp_vm.h"
56
57 static int load_trunk(struct ktap_parm *parm, unsigned long **buff)
58 {
59         int ret;
60         unsigned long *vmstart;
61
62         vmstart = vmalloc(parm->trunk_len);
63         if (!vmstart)
64                 return -ENOMEM;
65
66         ret = copy_from_user(vmstart, (void __user *)parm->trunk,
67                              parm->trunk_len);
68         if (ret < 0) {
69                 vfree(vmstart);
70                 return -EFAULT;
71         }
72
73         *buff = vmstart;
74         return 0;
75 }
76
77 static struct dentry *kp_dir_dentry;
78
79 /* Ktap Main Entry */
80 static int ktap_main(struct file *file, ktap_parm *parm)
81 {
82         unsigned long *buff = NULL;
83         ktap_state *ks;
84         ktap_closure *cl;
85         int start_time, delta_time;
86         int ret;
87
88         start_time = gettimeofday_us();
89
90         ks = kp_newstate(parm, kp_dir_dentry);
91         if (unlikely(!ks))
92                 return -ENOEXEC;
93
94         file->private_data = ks;
95
96         ret = load_trunk(parm, &buff);
97         if (ret) {
98                 pr_err("cannot load file\n");
99                 return ret;
100         }
101
102         cl = kp_load(ks, (unsigned char *)buff);
103
104         vfree(buff);
105
106         if (cl) {
107                 /* optimize bytecode before excuting */
108                 kp_optimize_code(ks, 0, cl->p);
109
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);
113         }
114
115         kp_final_exit(ks);
116         return ret;
117 }
118
119
120 static void print_version(void)
121 {
122 }
123
124 static long ktap_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
125 {
126         ktap_parm parm;
127         int ret;
128
129         switch (cmd) {
130         case KTAP_CMD_IOC_VERSION:
131                 print_version();
132                 return 0;
133         case KTAP_CMD_IOC_RUN:
134                 ret = copy_from_user(&parm, (void __user *)arg,
135                                      sizeof(ktap_parm));
136                 if (ret < 0)
137                         return -EFAULT;
138
139                 return ktap_main(file, &parm);
140         default:
141                 return -EINVAL;
142         };
143
144         return 0;
145 }
146
147 static const struct file_operations ktap_fops = {
148         .llseek                 = no_llseek,
149         .unlocked_ioctl         = ktap_ioctl,
150 };
151
152 static long ktapvm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
153 {
154         int new_fd, err;
155         struct file *new_file;
156
157         new_fd = get_unused_fd();
158         if (new_fd < 0)
159                 return new_fd;
160
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);
165                 return err;
166         }
167
168         file->private_data = NULL;
169         fd_install(new_fd, new_file);
170         return new_fd;
171 }
172
173 static const struct file_operations ktapvm_fops = {
174         .owner  = THIS_MODULE,
175         .unlocked_ioctl         = ktapvm_ioctl,
176 };
177
178 static int __init init_ktap(void)
179 {
180         struct dentry *ktapvm_dentry;
181
182         kp_dir_dentry = debugfs_create_dir("ktap", NULL);
183         if (!kp_dir_dentry) {
184                 pr_err("ktap: debugfs_create_dir failed\n");
185                 return -1;
186         }
187
188         ktapvm_dentry = debugfs_create_file("ktapvm", 0444, kp_dir_dentry, NULL,
189                                             &ktapvm_fops);
190
191         if (!ktapvm_dentry) {
192                 pr_err("ktapvm: cannot create ktapvm file\n");
193                 debugfs_remove_recursive(kp_dir_dentry);
194                 return -1;
195         }
196
197         kp_init_exit_instruction();
198
199         return 0;
200 }
201
202 static void __exit exit_ktap(void)
203 {
204         debugfs_remove_recursive(kp_dir_dentry);
205 }
206
207 module_init(init_ktap);
208 module_exit(exit_ktap);
209
210 MODULE_AUTHOR("Jovi Zhangwei <jovi.zhangwei@gmail.com>");
211 MODULE_DESCRIPTION("ktap");
212 MODULE_LICENSE("GPL");
213
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");
217