diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:05:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:05:51 +0000 |
commit | 5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 (patch) | |
tree | a94efe259b9009378be6d90eb30d2b019d95c194 /arch/riscv/lib/uaccess.S | |
parent | Initial commit. (diff) | |
download | linux-5d1646d90e1f2cceb9f0828f4b28318cd0ec7744.tar.xz linux-5d1646d90e1f2cceb9f0828f4b28318cd0ec7744.zip |
Adding upstream version 5.10.209.upstream/5.10.209
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'arch/riscv/lib/uaccess.S')
-rw-r--r-- | arch/riscv/lib/uaccess.S | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S new file mode 100644 index 000000000..fceaeb18c --- /dev/null +++ b/arch/riscv/lib/uaccess.S @@ -0,0 +1,126 @@ +#include <linux/linkage.h> +#include <asm-generic/export.h> +#include <asm/asm.h> +#include <asm/csr.h> + + .macro fixup op reg addr lbl +100: + \op \reg, \addr + .section __ex_table,"a" + .balign RISCV_SZPTR + RISCV_PTR 100b, \lbl + .previous + .endm + +ENTRY(__asm_copy_to_user) +ENTRY(__asm_copy_from_user) + + /* Enable access to user memory */ + li t6, SR_SUM + csrs CSR_STATUS, t6 + + add a3, a1, a2 + /* Use word-oriented copy only if low-order bits match */ + andi t0, a0, SZREG-1 + andi t1, a1, SZREG-1 + bne t0, t1, 2f + + addi t0, a1, SZREG-1 + andi t1, a3, ~(SZREG-1) + andi t0, t0, ~(SZREG-1) + /* + * a3: terminal address of source region + * t0: lowest XLEN-aligned address in source + * t1: highest XLEN-aligned address in source + */ + bgeu t0, t1, 2f + bltu a1, t0, 4f +1: + fixup REG_L, t2, (a1), 10f + fixup REG_S, t2, (a0), 10f + addi a1, a1, SZREG + addi a0, a0, SZREG + bltu a1, t1, 1b +2: + bltu a1, a3, 5f + +3: + /* Disable access to user memory */ + csrc CSR_STATUS, t6 + li a0, 0 + ret +4: /* Edge case: unalignment */ + fixup lbu, t2, (a1), 10f + fixup sb, t2, (a0), 10f + addi a1, a1, 1 + addi a0, a0, 1 + bltu a1, t0, 4b + j 1b +5: /* Edge case: remainder */ + fixup lbu, t2, (a1), 10f + fixup sb, t2, (a0), 10f + addi a1, a1, 1 + addi a0, a0, 1 + bltu a1, a3, 5b + j 3b +ENDPROC(__asm_copy_to_user) +ENDPROC(__asm_copy_from_user) +EXPORT_SYMBOL(__asm_copy_to_user) +EXPORT_SYMBOL(__asm_copy_from_user) + + +ENTRY(__clear_user) + + /* Enable access to user memory */ + li t6, SR_SUM + csrs CSR_STATUS, t6 + + add a3, a0, a1 + addi t0, a0, SZREG-1 + andi t1, a3, ~(SZREG-1) + andi t0, t0, ~(SZREG-1) + /* + * a3: terminal address of target region + * t0: lowest doubleword-aligned address in target region + * t1: highest doubleword-aligned address in target region + */ + bgeu t0, t1, 2f + bltu a0, t0, 4f +1: + fixup REG_S, zero, (a0), 11f + addi a0, a0, SZREG + bltu a0, t1, 1b +2: + bltu a0, a3, 5f + +3: + /* Disable access to user memory */ + csrc CSR_STATUS, t6 + li a0, 0 + ret +4: /* Edge case: unalignment */ + fixup sb, zero, (a0), 11f + addi a0, a0, 1 + bltu a0, t0, 4b + j 1b +5: /* Edge case: remainder */ + fixup sb, zero, (a0), 11f + addi a0, a0, 1 + bltu a0, a3, 5b + j 3b +ENDPROC(__clear_user) +EXPORT_SYMBOL(__clear_user) + + .section .fixup,"ax" + .balign 4 + /* Fixup code for __copy_user(10) and __clear_user(11) */ +10: + /* Disable access to user memory */ + csrs CSR_STATUS, t6 + mv a0, a2 + ret +11: + csrs CSR_STATUS, t6 + mv a0, a1 + ret + .previous |