12b8274f |
1 | /* test-nop-speed.c |
2 | * |
3 | */ |
4 | |
5 | #include <linux/module.h> |
6 | #include <linux/proc_fs.h> |
7 | #include <linux/sched.h> |
8 | #include <linux/timex.h> |
9 | #include <linux/marker.h> |
10 | #include <asm/ptrace.h> |
11 | |
7283e5cf |
12 | #define NR_TESTS 10000000 |
12b8274f |
13 | |
99bf728c |
14 | int var, var2; |
15 | |
12b8274f |
16 | struct proc_dir_entry *pentry = NULL; |
17 | |
18 | void empty(void) |
19 | { |
20 | asm volatile (""); |
99bf728c |
21 | var += 50; |
22 | var /= 10; |
23 | var *= var2; |
12b8274f |
24 | } |
25 | |
26 | void twobytesjump(void) |
27 | { |
28 | asm volatile ("jmp 1f\n\t" |
29 | ".byte 0x00, 0x00, 0x00\n\t" |
30 | "1:\n\t"); |
99bf728c |
31 | var += 50; |
32 | var /= 10; |
33 | var *= var2; |
12b8274f |
34 | } |
35 | |
36 | void fivebytesjump(void) |
37 | { |
f37346b4 |
38 | asm volatile (".byte 0xe9, 0x00, 0x00, 0x00, 0x00\n\t"); |
99bf728c |
39 | var += 50; |
40 | var /= 10; |
41 | var *= var2; |
12b8274f |
42 | } |
43 | |
44 | void threetwonops(void) |
45 | { |
f37346b4 |
46 | asm volatile (".byte 0x66,0x66,0x90,0x66,0x90\n\t"); |
99bf728c |
47 | var += 50; |
48 | var /= 10; |
49 | var *= var2; |
12b8274f |
50 | } |
51 | |
52 | void fivebytesnop(void) |
53 | { |
f37346b4 |
54 | asm volatile (".byte 0x66,0x66,0x66,0x66,0x90\n\t"); |
99bf728c |
55 | var += 50; |
56 | var /= 10; |
57 | var *= var2; |
12b8274f |
58 | } |
59 | |
60 | void fivebytespsixnop(void) |
61 | { |
f37346b4 |
62 | asm volatile (".byte 0x0f,0x1f,0x44,0x00,0\n\t"); |
99bf728c |
63 | var += 50; |
64 | var /= 10; |
65 | var *= var2; |
12b8274f |
66 | } |
67 | |
3b8909de |
68 | /* |
69 | * GENERIC_NOP1 GENERIC_NOP4, |
70 | * 1: nop |
71 | * _not_ nops in 64-bit mode. |
72 | * 4: leal 0x00(,%esi,1),%esi |
73 | */ |
74 | void genericfivebytesonefournops(void) |
75 | { |
76 | asm volatile (".byte 0x90,0x8d,0x74,0x26,0x00\n\t"); |
77 | var += 50; |
78 | var /= 10; |
79 | var *= var2; |
80 | } |
81 | |
82 | /* |
83 | * K7_NOP4 ASM_NOP1 |
84 | * 1: nop |
85 | * assumed _not_ to be nops in 64-bit mode. |
86 | * leal 0x00(,%eax,1),%eax |
87 | */ |
88 | void k7fivebytesonefournops(void) |
89 | { |
90 | asm volatile (".byte 0x90,0x8d,0x44,0x20,0x00\n\t"); |
91 | var += 50; |
92 | var /= 10; |
93 | var *= var2; |
94 | } |
95 | |
12b8274f |
96 | void perform_test(const char *name, void (*callback)(void)) |
97 | { |
98 | unsigned int i; |
99 | cycles_t cycles1, cycles2; |
100 | unsigned long flags; |
101 | |
102 | local_irq_save(flags); |
103 | rdtsc_barrier(); |
104 | cycles1 = get_cycles(); |
105 | rdtsc_barrier(); |
106 | for(i=0; i<NR_TESTS; i++) { |
107 | callback(); |
108 | } |
109 | rdtsc_barrier(); |
110 | cycles2 = get_cycles(); |
111 | rdtsc_barrier(); |
112 | local_irq_restore(flags); |
113 | printk("test %s cycles : %llu\n", name, cycles2-cycles1); |
114 | } |
115 | |
116 | static int my_open(struct inode *inode, struct file *file) |
117 | { |
118 | printk("NR_TESTS %d\n", NR_TESTS); |
119 | |
120 | perform_test("empty", empty); |
121 | perform_test("2-bytes jump", twobytesjump); |
122 | perform_test("5-bytes jump", fivebytesjump); |
123 | perform_test("3/2 nops", threetwonops); |
124 | perform_test("5-bytes nop with long prefix", fivebytesnop); |
125 | perform_test("5-bytes P6 nop", fivebytespsixnop); |
3b8909de |
126 | #ifdef CONFIG_X86_32 |
127 | perform_test("Generic 1/4 5-bytes nops", genericfivebytesonefournops); |
128 | perform_test("K7 1/4 5-bytes nops", k7fivebytesonefournops); |
129 | #endif |
12b8274f |
130 | |
131 | return -EPERM; |
132 | } |
133 | |
134 | |
135 | static struct file_operations my_operations = { |
136 | .open = my_open, |
137 | }; |
138 | |
139 | int init_module(void) |
140 | { |
141 | pentry = create_proc_entry("testnops", 0444, NULL); |
142 | if (pentry) |
143 | pentry->proc_fops = &my_operations; |
144 | |
145 | return 0; |
146 | } |
147 | |
148 | void cleanup_module(void) |
149 | { |
150 | remove_proc_entry("testnops", NULL); |
151 | } |
152 | |
153 | MODULE_LICENSE("GPL"); |
154 | MODULE_AUTHOR("Mathieu Desnoyers"); |
d7ff2f7d |
155 | MODULE_DESCRIPTION("NOP Test"); |