memory.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Test for x86 cache and memory instructions
  3. *
  4. * Copyright (c) 2015 Red Hat Inc
  5. *
  6. * Authors:
  7. * Eduardo Habkost <ehabkost@redhat.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2.
  10. */
  11. #include "libcflat.h"
  12. #include "desc.h"
  13. #include "processor.h"
  14. static long target;
  15. static volatile int ud;
  16. static volatile int isize;
  17. static void handle_ud(struct ex_regs *regs)
  18. {
  19. ud = 1;
  20. regs->rip += isize;
  21. }
  22. int main(int ac, char **av)
  23. {
  24. struct cpuid cpuid7, cpuid1;
  25. int xfail;
  26. setup_idt();
  27. handle_exception(UD_VECTOR, handle_ud);
  28. cpuid1 = cpuid(1);
  29. cpuid7 = cpuid_indexed(7, 0);
  30. /* 3-byte instructions: */
  31. isize = 3;
  32. xfail = !(cpuid1.d & (1U << 19)); /* CLFLUSH */
  33. ud = 0;
  34. asm volatile("clflush (%0)" : : "b" (&target));
  35. report_xfail("clflush", xfail, ud == 0);
  36. xfail = !(cpuid1.d & (1U << 25)); /* SSE */
  37. ud = 0;
  38. asm volatile("sfence");
  39. report_xfail("sfence", xfail, ud == 0);
  40. xfail = !(cpuid1.d & (1U << 26)); /* SSE2 */
  41. ud = 0;
  42. asm volatile("lfence");
  43. report_xfail("lfence", xfail, ud == 0);
  44. ud = 0;
  45. asm volatile("mfence");
  46. report_xfail("mfence", xfail, ud == 0);
  47. /* 4-byte instructions: */
  48. isize = 4;
  49. xfail = !(cpuid7.b & (1U << 23)); /* CLFLUSHOPT */
  50. ud = 0;
  51. /* clflushopt (%rbx): */
  52. asm volatile(".byte 0x66, 0x0f, 0xae, 0x3b" : : "b" (&target));
  53. report_xfail("clflushopt", xfail, ud == 0);
  54. xfail = !(cpuid7.b & (1U << 24)); /* CLWB */
  55. ud = 0;
  56. /* clwb (%rbx): */
  57. asm volatile(".byte 0x66, 0x0f, 0xae, 0x33" : : "b" (&target));
  58. report_xfail("clwb", xfail, ud == 0);
  59. ud = 0;
  60. /* clwb requires a memory operand, the following is NOT a valid
  61. * CLWB instruction (modrm == 0xF0).
  62. */
  63. asm volatile(".byte 0x66, 0x0f, 0xae, 0xf0");
  64. report("fake clwb", ud);
  65. xfail = !(cpuid7.b & (1U << 22)); /* PCOMMIT */
  66. ud = 0;
  67. /* pcommit: */
  68. asm volatile(".byte 0x66, 0x0f, 0xae, 0xf8");
  69. report_xfail("pcommit", xfail, ud == 0);
  70. return report_summary();
  71. }