]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
50af5ead | 2 | #include <linux/bug.h> |
ac61a757 VN |
3 | #include <linux/kernel.h> |
4 | ||
5 | #include "opcode.h" | |
6 | #include "selftest.h" | |
7 | ||
8 | struct selftest_opcode { | |
9 | unsigned int expected_size; | |
10 | const uint8_t *insn; | |
11 | const char *desc; | |
12 | }; | |
13 | ||
14 | static const struct selftest_opcode selftest_opcodes[] = { | |
15 | /* REP MOVS */ | |
16 | {1, "\xf3\xa4", "rep movsb <mem8>, <mem8>"}, | |
17 | {4, "\xf3\xa5", "rep movsl <mem32>, <mem32>"}, | |
18 | ||
19 | /* MOVZX / MOVZXD */ | |
20 | {1, "\x66\x0f\xb6\x51\xf8", "movzwq <mem8>, <reg16>"}, | |
21 | {1, "\x0f\xb6\x51\xf8", "movzwq <mem8>, <reg32>"}, | |
22 | ||
23 | /* MOVSX / MOVSXD */ | |
24 | {1, "\x66\x0f\xbe\x51\xf8", "movswq <mem8>, <reg16>"}, | |
25 | {1, "\x0f\xbe\x51\xf8", "movswq <mem8>, <reg32>"}, | |
26 | ||
27 | #ifdef CONFIG_X86_64 | |
28 | /* MOVZX / MOVZXD */ | |
29 | {1, "\x49\x0f\xb6\x51\xf8", "movzbq <mem8>, <reg64>"}, | |
30 | {2, "\x49\x0f\xb7\x51\xf8", "movzbq <mem16>, <reg64>"}, | |
31 | ||
32 | /* MOVSX / MOVSXD */ | |
33 | {1, "\x49\x0f\xbe\x51\xf8", "movsbq <mem8>, <reg64>"}, | |
34 | {2, "\x49\x0f\xbf\x51\xf8", "movsbq <mem16>, <reg64>"}, | |
35 | {4, "\x49\x63\x51\xf8", "movslq <mem32>, <reg64>"}, | |
36 | #endif | |
37 | }; | |
38 | ||
39 | static bool selftest_opcode_one(const struct selftest_opcode *op) | |
40 | { | |
41 | unsigned size; | |
42 | ||
43 | kmemcheck_opcode_decode(op->insn, &size); | |
44 | ||
45 | if (size == op->expected_size) | |
46 | return true; | |
47 | ||
48 | printk(KERN_WARNING "kmemcheck: opcode %s: expected size %d, got %d\n", | |
49 | op->desc, op->expected_size, size); | |
50 | return false; | |
51 | } | |
52 | ||
53 | static bool selftest_opcodes_all(void) | |
54 | { | |
55 | bool pass = true; | |
56 | unsigned int i; | |
57 | ||
58 | for (i = 0; i < ARRAY_SIZE(selftest_opcodes); ++i) | |
59 | pass = pass && selftest_opcode_one(&selftest_opcodes[i]); | |
60 | ||
61 | return pass; | |
62 | } | |
63 | ||
64 | bool kmemcheck_selftest(void) | |
65 | { | |
66 | bool pass = true; | |
67 | ||
68 | pass = pass && selftest_opcodes_all(); | |
69 | ||
70 | return pass; | |
71 | } |