^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Support for user memory access from kernel. This will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * probably be inlined for performance at some point, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * for ease of debug, and to a lesser degree for code size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * we implement here as subroutines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * For clear_user(), exploit previously defined copy_to_user function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * and the fact that we've got a handy zero page defined in kernel/head.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * dczero here would be even faster.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) __kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) long uncleared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) while (count > PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) uncleared = raw_copy_to_user(dest, &empty_zero_page, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (uncleared)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return count - (PAGE_SIZE - uncleared);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) count -= PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) dest += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) count = raw_copy_to_user(dest, &empty_zero_page, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned long clear_user_hexagon(void __user *dest, unsigned long count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (!access_ok(dest, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return __clear_user_hexagon(dest, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }