xsave.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * xsave/xrstor support.
  3. *
  4. * Author: Suresh Siddha <suresh.b.siddha@intel.com>
  5. */
  6. #include <linux/bootmem.h>
  7. #include <linux/compat.h>
  8. #include <asm/i387.h>
  9. /*
  10. * Supported feature mask by the CPU and the kernel.
  11. */
  12. unsigned int pcntxt_hmask, pcntxt_lmask;
  13. /*
  14. * Represents init state for the supported extended state.
  15. */
  16. struct xsave_struct *init_xstate_buf;
  17. /*
  18. * Enable the extended processor state save/restore feature
  19. */
  20. void __cpuinit xsave_init(void)
  21. {
  22. if (!cpu_has_xsave)
  23. return;
  24. set_in_cr4(X86_CR4_OSXSAVE);
  25. /*
  26. * Enable all the features that the HW is capable of
  27. * and the Linux kernel is aware of.
  28. *
  29. * xsetbv();
  30. */
  31. asm volatile(".byte 0x0f,0x01,0xd1" : : "c" (0),
  32. "a" (pcntxt_lmask), "d" (pcntxt_hmask));
  33. }
  34. /*
  35. * setup the xstate image representing the init state
  36. */
  37. void setup_xstate_init(void)
  38. {
  39. init_xstate_buf = alloc_bootmem(xstate_size);
  40. init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
  41. }
  42. /*
  43. * Enable and initialize the xsave feature.
  44. */
  45. void __init xsave_cntxt_init(void)
  46. {
  47. unsigned int eax, ebx, ecx, edx;
  48. cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx);
  49. pcntxt_lmask = eax;
  50. pcntxt_hmask = edx;
  51. if ((pcntxt_lmask & XSTATE_FPSSE) != XSTATE_FPSSE) {
  52. printk(KERN_ERR "FP/SSE not shown under xsave features %x\n",
  53. pcntxt_lmask);
  54. BUG();
  55. }
  56. /*
  57. * for now OS knows only about FP/SSE
  58. */
  59. pcntxt_lmask = pcntxt_lmask & XCNTXT_LMASK;
  60. pcntxt_hmask = pcntxt_hmask & XCNTXT_HMASK;
  61. xsave_init();
  62. /*
  63. * Recompute the context size for enabled features
  64. */
  65. cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx);
  66. xstate_size = ebx;
  67. setup_xstate_init();
  68. printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%Lx, "
  69. "cntxt size 0x%x\n",
  70. (pcntxt_lmask | ((u64) pcntxt_hmask << 32)), xstate_size);
  71. }