18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
38c2ecf20Sopenharmony_ci#include <linux/errno.h>
48c2ecf20Sopenharmony_ci#include <linux/init.h>
58c2ecf20Sopenharmony_ci#include <linux/pgtable.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <asm/proto.h>
88c2ecf20Sopenharmony_ci#include <asm/cpufeature.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cistatic int disable_nx;
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci * noexec = on|off
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * Control non-executable mappings for processes.
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * on      Enable
188c2ecf20Sopenharmony_ci * off     Disable
198c2ecf20Sopenharmony_ci */
208c2ecf20Sopenharmony_cistatic int __init noexec_setup(char *str)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	if (!str)
238c2ecf20Sopenharmony_ci		return -EINVAL;
248c2ecf20Sopenharmony_ci	if (!strncmp(str, "on", 2)) {
258c2ecf20Sopenharmony_ci		disable_nx = 0;
268c2ecf20Sopenharmony_ci	} else if (!strncmp(str, "off", 3)) {
278c2ecf20Sopenharmony_ci		disable_nx = 1;
288c2ecf20Sopenharmony_ci	}
298c2ecf20Sopenharmony_ci	x86_configure_nx();
308c2ecf20Sopenharmony_ci	return 0;
318c2ecf20Sopenharmony_ci}
328c2ecf20Sopenharmony_ciearly_param("noexec", noexec_setup);
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_civoid x86_configure_nx(void)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx)
378c2ecf20Sopenharmony_ci		__supported_pte_mask |= _PAGE_NX;
388c2ecf20Sopenharmony_ci	else
398c2ecf20Sopenharmony_ci		__supported_pte_mask &= ~_PAGE_NX;
408c2ecf20Sopenharmony_ci}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_civoid __init x86_report_nx(void)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	if (!boot_cpu_has(X86_FEATURE_NX)) {
458c2ecf20Sopenharmony_ci		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
468c2ecf20Sopenharmony_ci		       "missing in CPU!\n");
478c2ecf20Sopenharmony_ci	} else {
488c2ecf20Sopenharmony_ci#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
498c2ecf20Sopenharmony_ci		if (disable_nx) {
508c2ecf20Sopenharmony_ci			printk(KERN_INFO "NX (Execute Disable) protection: "
518c2ecf20Sopenharmony_ci			       "disabled by kernel command line option\n");
528c2ecf20Sopenharmony_ci		} else {
538c2ecf20Sopenharmony_ci			printk(KERN_INFO "NX (Execute Disable) protection: "
548c2ecf20Sopenharmony_ci			       "active\n");
558c2ecf20Sopenharmony_ci		}
568c2ecf20Sopenharmony_ci#else
578c2ecf20Sopenharmony_ci		/* 32bit non-PAE kernel, NX cannot be used */
588c2ecf20Sopenharmony_ci		printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
598c2ecf20Sopenharmony_ci		       "cannot be enabled: non-PAE kernel!\n");
608c2ecf20Sopenharmony_ci#endif
618c2ecf20Sopenharmony_ci	}
628c2ecf20Sopenharmony_ci}
63