setup_nx.c 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #include <linux/spinlock.h>
  2. #include <linux/errno.h>
  3. #include <linux/init.h>
  4. #include <asm/pgtable.h>
  5. int nx_enabled;
  6. #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
  7. static int disable_nx __cpuinitdata;
  8. /*
  9. * noexec = on|off
  10. *
  11. * Control non-executable mappings for processes.
  12. *
  13. * on Enable
  14. * off Disable
  15. */
  16. static int __init noexec_setup(char *str)
  17. {
  18. if (!str)
  19. return -EINVAL;
  20. if (!strncmp(str, "on", 2)) {
  21. __supported_pte_mask |= _PAGE_NX;
  22. disable_nx = 0;
  23. } else if (!strncmp(str, "off", 3)) {
  24. disable_nx = 1;
  25. __supported_pte_mask &= ~_PAGE_NX;
  26. }
  27. return 0;
  28. }
  29. early_param("noexec", noexec_setup);
  30. #endif
  31. #ifdef CONFIG_X86_PAE
  32. void __init set_nx(void)
  33. {
  34. unsigned int v[4], l, h;
  35. if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
  36. cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
  37. if ((v[3] & (1 << 20)) && !disable_nx) {
  38. rdmsr(MSR_EFER, l, h);
  39. l |= EFER_NX;
  40. wrmsr(MSR_EFER, l, h);
  41. nx_enabled = 1;
  42. __supported_pte_mask |= _PAGE_NX;
  43. }
  44. }
  45. }
  46. #else
  47. void set_nx(void)
  48. {
  49. }
  50. #endif
  51. #ifdef CONFIG_X86_64
  52. void __cpuinit check_efer(void)
  53. {
  54. unsigned long efer;
  55. rdmsrl(MSR_EFER, efer);
  56. if (!(efer & EFER_NX) || disable_nx)
  57. __supported_pte_mask &= ~_PAGE_NX;
  58. }
  59. #endif