root/arch/riscv/lib/uaccess.S

/* [<][>][^][v][top][bottom][index][help] */
   1 #include <linux/linkage.h>
   2 #include <asm/asm.h>
   3 #include <asm/csr.h>
   4 
   5         .altmacro
   6         .macro fixup op reg addr lbl
   7         LOCAL _epc
   8 _epc:
   9         \op \reg, \addr
  10         .section __ex_table,"a"
  11         .balign RISCV_SZPTR
  12         RISCV_PTR _epc, \lbl
  13         .previous
  14         .endm
  15 
  16 ENTRY(__asm_copy_to_user)
  17 ENTRY(__asm_copy_from_user)
  18 
  19         /* Enable access to user memory */
  20         li t6, SR_SUM
  21         csrs CSR_SSTATUS, t6
  22 
  23         add a3, a1, a2
  24         /* Use word-oriented copy only if low-order bits match */
  25         andi t0, a0, SZREG-1
  26         andi t1, a1, SZREG-1
  27         bne t0, t1, 2f
  28 
  29         addi t0, a1, SZREG-1
  30         andi t1, a3, ~(SZREG-1)
  31         andi t0, t0, ~(SZREG-1)
  32         /*
  33          * a3: terminal address of source region
  34          * t0: lowest XLEN-aligned address in source
  35          * t1: highest XLEN-aligned address in source
  36          */
  37         bgeu t0, t1, 2f
  38         bltu a1, t0, 4f
  39 1:
  40         fixup REG_L, t2, (a1), 10f
  41         fixup REG_S, t2, (a0), 10f
  42         addi a1, a1, SZREG
  43         addi a0, a0, SZREG
  44         bltu a1, t1, 1b
  45 2:
  46         bltu a1, a3, 5f
  47 
  48 3:
  49         /* Disable access to user memory */
  50         csrc CSR_SSTATUS, t6
  51         li a0, 0
  52         ret
  53 4: /* Edge case: unalignment */
  54         fixup lbu, t2, (a1), 10f
  55         fixup sb, t2, (a0), 10f
  56         addi a1, a1, 1
  57         addi a0, a0, 1
  58         bltu a1, t0, 4b
  59         j 1b
  60 5: /* Edge case: remainder */
  61         fixup lbu, t2, (a1), 10f
  62         fixup sb, t2, (a0), 10f
  63         addi a1, a1, 1
  64         addi a0, a0, 1
  65         bltu a1, a3, 5b
  66         j 3b
  67 ENDPROC(__asm_copy_to_user)
  68 ENDPROC(__asm_copy_from_user)
  69 
  70 
  71 ENTRY(__clear_user)
  72 
  73         /* Enable access to user memory */
  74         li t6, SR_SUM
  75         csrs CSR_SSTATUS, t6
  76 
  77         add a3, a0, a1
  78         addi t0, a0, SZREG-1
  79         andi t1, a3, ~(SZREG-1)
  80         andi t0, t0, ~(SZREG-1)
  81         /*
  82          * a3: terminal address of target region
  83          * t0: lowest doubleword-aligned address in target region
  84          * t1: highest doubleword-aligned address in target region
  85          */
  86         bgeu t0, t1, 2f
  87         bltu a0, t0, 4f
  88 1:
  89         fixup REG_S, zero, (a0), 11f
  90         addi a0, a0, SZREG
  91         bltu a0, t1, 1b
  92 2:
  93         bltu a0, a3, 5f
  94 
  95 3:
  96         /* Disable access to user memory */
  97         csrc CSR_SSTATUS, t6
  98         li a0, 0
  99         ret
 100 4: /* Edge case: unalignment */
 101         fixup sb, zero, (a0), 11f
 102         addi a0, a0, 1
 103         bltu a0, t0, 4b
 104         j 1b
 105 5: /* Edge case: remainder */
 106         fixup sb, zero, (a0), 11f
 107         addi a0, a0, 1
 108         bltu a0, a3, 5b
 109         j 3b
 110 ENDPROC(__clear_user)
 111 
 112         .section .fixup,"ax"
 113         .balign 4
 114         /* Fixup code for __copy_user(10) and __clear_user(11) */
 115 10:
 116         /* Disable access to user memory */
 117         csrs CSR_SSTATUS, t6
 118         mv a0, a2
 119         ret
 120 11:
 121         csrs CSR_SSTATUS, t6
 122         mv a0, a1
 123         ret
 124         .previous

/* [<][>][^][v][top][bottom][index][help] */