GNU Linux-libre 6.8.7-gnu
[releases.git] / arch / riscv / lib / riscv_v_helpers.c
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
17 size_t riscv_v_usercopy_threshold = CONFIG_RISCV_ISA_V_UCOPY_THRESHOLD;
18 int __asm_vector_usercopy(void *dst, void *src, size_t n);
19 int fallback_scalar_usercopy(void *dst, void *src, size_t n);
20 asmlinkage 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
42 fallback:
43         return fallback_scalar_usercopy(dst, src, n);
44 }
45 #endif