18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci/* 78c2ecf20Sopenharmony_ci * Support for user memory access from kernel. This will 88c2ecf20Sopenharmony_ci * probably be inlined for performance at some point, but 98c2ecf20Sopenharmony_ci * for ease of debug, and to a lesser degree for code size, 108c2ecf20Sopenharmony_ci * we implement here as subroutines. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci#include <linux/types.h> 138c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 148c2ecf20Sopenharmony_ci#include <linux/pgtable.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * For clear_user(), exploit previously defined copy_to_user function 188c2ecf20Sopenharmony_ci * and the fact that we've got a handy zero page defined in kernel/head.S 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * dczero here would be even faster. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci__kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci long uncleared; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci while (count > PAGE_SIZE) { 278c2ecf20Sopenharmony_ci uncleared = raw_copy_to_user(dest, &empty_zero_page, PAGE_SIZE); 288c2ecf20Sopenharmony_ci if (uncleared) 298c2ecf20Sopenharmony_ci return count - (PAGE_SIZE - uncleared); 308c2ecf20Sopenharmony_ci count -= PAGE_SIZE; 318c2ecf20Sopenharmony_ci dest += PAGE_SIZE; 328c2ecf20Sopenharmony_ci } 338c2ecf20Sopenharmony_ci if (count) 348c2ecf20Sopenharmony_ci count = raw_copy_to_user(dest, &empty_zero_page, count); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci return count; 378c2ecf20Sopenharmony_ci} 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ciunsigned long clear_user_hexagon(void __user *dest, unsigned long count) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci if (!access_ok(dest, count)) 428c2ecf20Sopenharmony_ci return count; 438c2ecf20Sopenharmony_ci else 448c2ecf20Sopenharmony_ci return __clear_user_hexagon(dest, count); 458c2ecf20Sopenharmony_ci} 46