1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2023 SiFive
4 * Author: Andy Chiu <andy.chiu@sifive.com>
5 */
6#include <linux/linkage.h>
7#include <asm/asm.h>
8
9#include <asm/vector.h>
10#include <asm/simd.h>
11
12#ifdef CONFIG_MMU
13#include <asm/asm-prototypes.h>
14#endif
15
16#ifdef CONFIG_MMU
17size_t riscv_v_usercopy_threshold = CONFIG_RISCV_ISA_V_UCOPY_THRESHOLD;
18int __asm_vector_usercopy(void *dst, void *src, size_t n);
19int fallback_scalar_usercopy(void *dst, void *src, size_t n);
20asmlinkage int enter_vector_usercopy(void *dst, void *src, size_t n)
21{
22	size_t remain, copied;
23
24	/* skip has_vector() check because it has been done by the asm  */
25	if (!may_use_simd())
26		goto fallback;
27
28	kernel_vector_begin();
29	remain = __asm_vector_usercopy(dst, src, n);
30	kernel_vector_end();
31
32	if (remain) {
33		copied = n - remain;
34		dst += copied;
35		src += copied;
36		n = remain;
37		goto fallback;
38	}
39
40	return remain;
41
42fallback:
43	return fallback_scalar_usercopy(dst, src, n);
44}
45#endif
46