selftest.c 1.6 KB

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