2024-01-15 05:59:24 +00:00
|
|
|
// 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);
|
2025-06-02 21:39:14 +02:00
|
|
|
int __asm_vector_usercopy_sum_enabled(void *dst, void *src, size_t n);
|
2024-01-15 05:59:24 +00:00
|
|
|
int fallback_scalar_usercopy(void *dst, void *src, size_t n);
|
2025-06-02 21:39:14 +02:00
|
|
|
int fallback_scalar_usercopy_sum_enabled(void *dst, void *src, size_t n);
|
|
|
|
asmlinkage int enter_vector_usercopy(void *dst, void *src, size_t n,
|
|
|
|
bool enable_sum)
|
2024-01-15 05:59:24 +00:00
|
|
|
{
|
|
|
|
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();
|
2025-06-02 21:39:14 +02:00
|
|
|
remain = enable_sum ? __asm_vector_usercopy(dst, src, n) :
|
|
|
|
__asm_vector_usercopy_sum_enabled(dst, src, n);
|
2024-01-15 05:59:24 +00:00
|
|
|
kernel_vector_end();
|
|
|
|
|
|
|
|
if (remain) {
|
|
|
|
copied = n - remain;
|
|
|
|
dst += copied;
|
|
|
|
src += copied;
|
|
|
|
n = remain;
|
|
|
|
goto fallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
return remain;
|
|
|
|
|
|
|
|
fallback:
|
2025-06-02 21:39:14 +02:00
|
|
|
return enable_sum ? fallback_scalar_usercopy(dst, src, n) :
|
|
|
|
fallback_scalar_usercopy_sum_enabled(dst, src, n);
|
2024-01-15 05:59:24 +00:00
|
|
|
}
|
|
|
|
#endif
|