OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [misc/] [lkdtm.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Kprobe module for testing crash dumps
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
 *
18
 * Copyright (C) IBM Corporation, 2006
19
 *
20
 * Author: Ankita Garg <ankita@in.ibm.com>
21
 *
22
 * This module induces system failures at predefined crashpoints to
23
 * evaluate the reliability of crash dumps obtained using different dumping
24
 * solutions.
25
 *
26
 * It is adapted from the Linux Kernel Dump Test Tool by
27
 * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
28
 *
29
 * Usage :  insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
30
 *                                                      [cpoint_count={>0}]
31
 *
32
 * recur_count : Recursion level for the stack overflow test. Default is 10.
33
 *
34
 * cpoint_name : Crash point where the kernel is to be crashed. It can be
35
 *               one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
36
 *               FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
37
 *               IDE_CORE_CP
38
 *
39
 * cpoint_type : Indicates the action to be taken on hitting the crash point.
40
 *               It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW
41
 *
42
 * cpoint_count : Indicates the number of times the crash point is to be hit
43
 *                to trigger an action. The default is 10.
44
 */
45
 
46
#include <linux/kernel.h>
47
#include <linux/fs.h>
48
#include <linux/module.h>
49
#include <linux/buffer_head.h>
50
#include <linux/kprobes.h>
51
#include <linux/list.h>
52
#include <linux/init.h>
53
#include <linux/interrupt.h>
54
#include <linux/hrtimer.h>
55
#include <scsi/scsi_cmnd.h>
56
 
57
#ifdef CONFIG_IDE
58
#include <linux/ide.h>
59
#endif
60
 
61
#define NUM_CPOINTS 8
62
#define NUM_CPOINT_TYPES 5
63
#define DEFAULT_COUNT 10
64
#define REC_NUM_DEFAULT 10
65
 
66
enum cname {
67
        INVALID,
68
        INT_HARDWARE_ENTRY,
69
        INT_HW_IRQ_EN,
70
        INT_TASKLET_ENTRY,
71
        FS_DEVRW,
72
        MEM_SWAPOUT,
73
        TIMERADD,
74
        SCSI_DISPATCH_CMD,
75
        IDE_CORE_CP
76
};
77
 
78
enum ctype {
79
        NONE,
80
        PANIC,
81
        BUG,
82
        EXCEPTION,
83
        LOOP,
84
        OVERFLOW
85
};
86
 
87
static char* cp_name[] = {
88
        "INT_HARDWARE_ENTRY",
89
        "INT_HW_IRQ_EN",
90
        "INT_TASKLET_ENTRY",
91
        "FS_DEVRW",
92
        "MEM_SWAPOUT",
93
        "TIMERADD",
94
        "SCSI_DISPATCH_CMD",
95
        "IDE_CORE_CP"
96
};
97
 
98
static char* cp_type[] = {
99
        "PANIC",
100
        "BUG",
101
        "EXCEPTION",
102
        "LOOP",
103
        "OVERFLOW"
104
};
105
 
106
static struct jprobe lkdtm;
107
 
108
static int lkdtm_parse_commandline(void);
109
static void lkdtm_handler(void);
110
 
111
static char* cpoint_name;
112
static char* cpoint_type;
113
static int cpoint_count = DEFAULT_COUNT;
114
static int recur_count = REC_NUM_DEFAULT;
115
 
116
static enum cname cpoint = INVALID;
117
static enum ctype cptype = NONE;
118
static int count = DEFAULT_COUNT;
119
 
120
module_param(recur_count, int, 0644);
121
MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
122
                                 "default is 10");
123
module_param(cpoint_name, charp, 0644);
124
MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
125
module_param(cpoint_type, charp, 0644);
126
MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\
127
                                "hitting the crash point");
128
module_param(cpoint_count, int, 0644);
129
MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\
130
                                "crash point is to be hit to trigger action");
131
 
132
unsigned int jp_do_irq(unsigned int irq)
133
{
134
        lkdtm_handler();
135
        jprobe_return();
136
        return 0;
137
}
138
 
139
irqreturn_t jp_handle_irq_event(unsigned int irq, struct irqaction *action)
140
{
141
        lkdtm_handler();
142
        jprobe_return();
143
        return 0;
144
}
145
 
146
void jp_tasklet_action(struct softirq_action *a)
147
{
148
        lkdtm_handler();
149
        jprobe_return();
150
}
151
 
152
void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
153
{
154
        lkdtm_handler();
155
        jprobe_return();
156
}
157
 
158
struct scan_control;
159
 
160
unsigned long jp_shrink_inactive_list(unsigned long max_scan,
161
                                struct zone *zone, struct scan_control *sc)
162
{
163
        lkdtm_handler();
164
        jprobe_return();
165
        return 0;
166
}
167
 
168
int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
169
                                const enum hrtimer_mode mode)
170
{
171
        lkdtm_handler();
172
        jprobe_return();
173
        return 0;
174
}
175
 
176
int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
177
{
178
        lkdtm_handler();
179
        jprobe_return();
180
        return 0;
181
}
182
 
183
#ifdef CONFIG_IDE
184
int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
185
                        struct block_device *bdev, unsigned int cmd,
186
                        unsigned long arg)
187
{
188
        lkdtm_handler();
189
        jprobe_return();
190
        return 0;
191
}
192
#endif
193
 
194
static int lkdtm_parse_commandline(void)
195
{
196
        int i;
197
 
198
        if (cpoint_name == INVALID || cpoint_type == NONE ||
199
                                        cpoint_count < 1 || recur_count < 1)
200
                return -EINVAL;
201
 
202
        for (i = 0; i < NUM_CPOINTS; ++i) {
203
                if (!strcmp(cpoint_name, cp_name[i])) {
204
                        cpoint = i + 1;
205
                        break;
206
                }
207
        }
208
 
209
        for (i = 0; i < NUM_CPOINT_TYPES; ++i) {
210
                if (!strcmp(cpoint_type, cp_type[i])) {
211
                        cptype = i + 1;
212
                        break;
213
                }
214
        }
215
 
216
        if (cpoint == INVALID || cptype == NONE)
217
                return -EINVAL;
218
 
219
        count = cpoint_count;
220
 
221
        return 0;
222
}
223
 
224
static int recursive_loop(int a)
225
{
226
        char buf[1024];
227
 
228
        memset(buf,0xFF,1024);
229
        recur_count--;
230
        if (!recur_count)
231
                return 0;
232
        else
233
                return recursive_loop(a);
234
}
235
 
236
void lkdtm_handler(void)
237
{
238
        printk(KERN_INFO "lkdtm : Crash point %s of type %s hit\n",
239
                                         cpoint_name, cpoint_type);
240
        --count;
241
 
242
        if (count == 0) {
243
                switch (cptype) {
244
                case NONE:
245
                        break;
246
                case PANIC:
247
                        printk(KERN_INFO "lkdtm : PANIC\n");
248
                        panic("dumptest");
249
                        break;
250
                case BUG:
251
                        printk(KERN_INFO "lkdtm : BUG\n");
252
                        BUG();
253
                        break;
254
                case EXCEPTION:
255
                        printk(KERN_INFO "lkdtm : EXCEPTION\n");
256
                        *((int *) 0) = 0;
257
                        break;
258
                case LOOP:
259
                        printk(KERN_INFO "lkdtm : LOOP\n");
260
                        for (;;);
261
                        break;
262
                case OVERFLOW:
263
                        printk(KERN_INFO "lkdtm : OVERFLOW\n");
264
                        (void) recursive_loop(0);
265
                        break;
266
                default:
267
                        break;
268
                }
269
                count = cpoint_count;
270
        }
271
}
272
 
273
int lkdtm_module_init(void)
274
{
275
        int ret;
276
 
277
        if (lkdtm_parse_commandline() == -EINVAL) {
278
                printk(KERN_INFO "lkdtm : Invalid command\n");
279
                return -EINVAL;
280
        }
281
 
282
        switch (cpoint) {
283
        case INT_HARDWARE_ENTRY:
284
                lkdtm.kp.symbol_name = "__do_IRQ";
285
                lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
286
                break;
287
        case INT_HW_IRQ_EN:
288
                lkdtm.kp.symbol_name = "handle_IRQ_event";
289
                lkdtm.entry = (kprobe_opcode_t*) jp_handle_irq_event;
290
                break;
291
        case INT_TASKLET_ENTRY:
292
                lkdtm.kp.symbol_name = "tasklet_action";
293
                lkdtm.entry = (kprobe_opcode_t*) jp_tasklet_action;
294
                break;
295
        case FS_DEVRW:
296
                lkdtm.kp.symbol_name = "ll_rw_block";
297
                lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block;
298
                break;
299
        case MEM_SWAPOUT:
300
                lkdtm.kp.symbol_name = "shrink_inactive_list";
301
                lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list;
302
                break;
303
        case TIMERADD:
304
                lkdtm.kp.symbol_name = "hrtimer_start";
305
                lkdtm.entry = (kprobe_opcode_t*) jp_hrtimer_start;
306
                break;
307
        case SCSI_DISPATCH_CMD:
308
                lkdtm.kp.symbol_name = "scsi_dispatch_cmd";
309
                lkdtm.entry = (kprobe_opcode_t*) jp_scsi_dispatch_cmd;
310
                break;
311
        case IDE_CORE_CP:
312
#ifdef CONFIG_IDE
313
                lkdtm.kp.symbol_name = "generic_ide_ioctl";
314
                lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
315
#else
316
                printk(KERN_INFO "lkdtm : Crash point not available\n");
317
#endif
318
                break;
319
        default:
320
                printk(KERN_INFO "lkdtm : Invalid Crash Point\n");
321
                break;
322
        }
323
 
324
        if ((ret = register_jprobe(&lkdtm)) < 0) {
325
                printk(KERN_INFO "lkdtm : Couldn't register jprobe\n");
326
                return ret;
327
        }
328
 
329
        printk(KERN_INFO "lkdtm : Crash point %s of type %s registered\n",
330
                                                cpoint_name, cpoint_type);
331
        return 0;
332
}
333
 
334
void lkdtm_module_exit(void)
335
{
336
        unregister_jprobe(&lkdtm);
337
        printk(KERN_INFO "lkdtm : Crash point unregistered\n");
338
}
339
 
340
module_init(lkdtm_module_init);
341
module_exit(lkdtm_module_exit);
342
 
343
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.