selftest.c 1.5 KB

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