46 lines
977 B
C
46 lines
977 B
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (C) 2023 SiFive
|
|
* Author: Andy Chiu <andy.chiu@sifive.com>
|
|
*/
|
|
#include <linux/linkage.h>
|
|
#include <asm/asm.h>
|
|
|
|
#include <asm/vector.h>
|
|
#include <asm/simd.h>
|
|
|
|
#ifdef CONFIG_MMU
|
|
#include <asm/asm-prototypes.h>
|
|
#endif
|
|
|
|
#ifdef CONFIG_MMU
|
|
size_t riscv_v_usercopy_threshold = CONFIG_RISCV_ISA_V_UCOPY_THRESHOLD;
|
|
int __asm_vector_usercopy(void *dst, void *src, size_t n);
|
|
int fallback_scalar_usercopy(void *dst, void *src, size_t n);
|
|
asmlinkage int enter_vector_usercopy(void *dst, void *src, size_t n)
|
|
{
|
|
size_t remain, copied;
|
|
|
|
/* skip has_vector() check because it has been done by the asm */
|
|
if (!may_use_simd())
|
|
goto fallback;
|
|
|
|
kernel_vector_begin();
|
|
remain = __asm_vector_usercopy(dst, src, n);
|
|
kernel_vector_end();
|
|
|
|
if (remain) {
|
|
copied = n - remain;
|
|
dst += copied;
|
|
src += copied;
|
|
n = remain;
|
|
goto fallback;
|
|
}
|
|
|
|
return remain;
|
|
|
|
fallback:
|
|
return fallback_scalar_usercopy(dst, src, n);
|
|
}
|
|
#endif
|