18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
48c2ecf20Sopenharmony_ci#include <linux/kernel.h>
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
78c2ecf20Sopenharmony_cibool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
88c2ecf20Sopenharmony_ci{
98c2ecf20Sopenharmony_ci	unsigned long vaddr = (unsigned long)unsafe_src;
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci	/*
128c2ecf20Sopenharmony_ci	 * Do not allow userspace addresses.  This disallows
138c2ecf20Sopenharmony_ci	 * normal userspace and the userspace guard page:
148c2ecf20Sopenharmony_ci	 */
158c2ecf20Sopenharmony_ci	if (vaddr < TASK_SIZE_MAX + PAGE_SIZE)
168c2ecf20Sopenharmony_ci		return false;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	/*
198c2ecf20Sopenharmony_ci	 * Allow everything during early boot before 'x86_virt_bits'
208c2ecf20Sopenharmony_ci	 * is initialized.  Needed for instruction decoding in early
218c2ecf20Sopenharmony_ci	 * exception handlers.
228c2ecf20Sopenharmony_ci	 */
238c2ecf20Sopenharmony_ci	if (!boot_cpu_data.x86_virt_bits)
248c2ecf20Sopenharmony_ci		return true;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	return __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci#else
298c2ecf20Sopenharmony_cibool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	return (unsigned long)unsafe_src >= TASK_SIZE_MAX;
328c2ecf20Sopenharmony_ci}
338c2ecf20Sopenharmony_ci#endif
34