162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* 762306a36Sopenharmony_ci * Support for user memory access from kernel. This will 862306a36Sopenharmony_ci * probably be inlined for performance at some point, but 962306a36Sopenharmony_ci * for ease of debug, and to a lesser degree for code size, 1062306a36Sopenharmony_ci * we implement here as subroutines. 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci#include <linux/types.h> 1362306a36Sopenharmony_ci#include <linux/uaccess.h> 1462306a36Sopenharmony_ci#include <linux/pgtable.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * For clear_user(), exploit previously defined copy_to_user function 1862306a36Sopenharmony_ci * and the fact that we've got a handy zero page defined in kernel/head.S 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * dczero here would be even faster. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ci__kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci long uncleared; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci while (count > PAGE_SIZE) { 2762306a36Sopenharmony_ci uncleared = raw_copy_to_user(dest, &empty_zero_page, PAGE_SIZE); 2862306a36Sopenharmony_ci if (uncleared) 2962306a36Sopenharmony_ci return count - (PAGE_SIZE - uncleared); 3062306a36Sopenharmony_ci count -= PAGE_SIZE; 3162306a36Sopenharmony_ci dest += PAGE_SIZE; 3262306a36Sopenharmony_ci } 3362306a36Sopenharmony_ci if (count) 3462306a36Sopenharmony_ci count = raw_copy_to_user(dest, &empty_zero_page, count); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci return count; 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ciunsigned long clear_user_hexagon(void __user *dest, unsigned long count) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci if (!access_ok(dest, count)) 4262306a36Sopenharmony_ci return count; 4362306a36Sopenharmony_ci else 4462306a36Sopenharmony_ci return __clear_user_hexagon(dest, count); 4562306a36Sopenharmony_ci} 46