root/arch/arm/include/asm/uaccess-asm.h

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

INCLUDED FROM


   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 
   3 #ifndef __ASM_UACCESS_ASM_H__
   4 #define __ASM_UACCESS_ASM_H__
   5 
   6 #include <asm/asm-offsets.h>
   7 #include <asm/domain.h>
   8 #include <asm/memory.h>
   9 #include <asm/thread_info.h>
  10 
  11         .macro  csdb
  12 #ifdef CONFIG_THUMB2_KERNEL
  13         .inst.w 0xf3af8014
  14 #else
  15         .inst   0xe320f014
  16 #endif
  17         .endm
  18 
  19         .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
  20 #ifndef CONFIG_CPU_USE_DOMAINS
  21         adds    \tmp, \addr, #\size - 1
  22         sbcscc  \tmp, \tmp, \limit
  23         bcs     \bad
  24 #ifdef CONFIG_CPU_SPECTRE
  25         movcs   \addr, #0
  26         csdb
  27 #endif
  28 #endif
  29         .endm
  30 
  31         .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
  32 #ifdef CONFIG_CPU_SPECTRE
  33         sub     \tmp, \limit, #1
  34         subs    \tmp, \tmp, \addr       @ tmp = limit - 1 - addr
  35         addhs   \tmp, \tmp, #1          @ if (tmp >= 0) {
  36         subshs  \tmp, \tmp, \size       @ tmp = limit - (addr + size) }
  37         movlo   \addr, #0               @ if (tmp < 0) addr = NULL
  38         csdb
  39 #endif
  40         .endm
  41 
  42         .macro  uaccess_disable, tmp, isb=1
  43 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
  44         /*
  45          * Whenever we re-enter userspace, the domains should always be
  46          * set appropriately.
  47          */
  48         mov     \tmp, #DACR_UACCESS_DISABLE
  49         mcr     p15, 0, \tmp, c3, c0, 0         @ Set domain register
  50         .if     \isb
  51         instr_sync
  52         .endif
  53 #endif
  54         .endm
  55 
  56         .macro  uaccess_enable, tmp, isb=1
  57 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
  58         /*
  59          * Whenever we re-enter userspace, the domains should always be
  60          * set appropriately.
  61          */
  62         mov     \tmp, #DACR_UACCESS_ENABLE
  63         mcr     p15, 0, \tmp, c3, c0, 0
  64         .if     \isb
  65         instr_sync
  66         .endif
  67 #endif
  68         .endm
  69 
  70 #if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS)
  71 #define DACR(x...)      x
  72 #else
  73 #define DACR(x...)
  74 #endif
  75 
  76         /*
  77          * Save the address limit on entry to a privileged exception.
  78          *
  79          * If we are using the DACR for kernel access by the user accessors
  80          * (CONFIG_CPU_USE_DOMAINS=y), always reset the DACR kernel domain
  81          * back to client mode, whether or not \disable is set.
  82          *
  83          * If we are using SW PAN, set the DACR user domain to no access
  84          * if \disable is set.
  85          */
  86         .macro  uaccess_entry, tsk, tmp0, tmp1, tmp2, disable
  87         ldr     \tmp1, [\tsk, #TI_ADDR_LIMIT]
  88         mov     \tmp2, #TASK_SIZE
  89         str     \tmp2, [\tsk, #TI_ADDR_LIMIT]
  90  DACR(  mrc     p15, 0, \tmp0, c3, c0, 0)
  91  DACR(  str     \tmp0, [sp, #SVC_DACR])
  92         str     \tmp1, [sp, #SVC_ADDR_LIMIT]
  93         .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN)
  94         /* kernel=client, user=no access */
  95         mov     \tmp2, #DACR_UACCESS_DISABLE
  96         mcr     p15, 0, \tmp2, c3, c0, 0
  97         instr_sync
  98         .elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS)
  99         /* kernel=client */
 100         bic     \tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL)
 101         orr     \tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT)
 102         mcr     p15, 0, \tmp2, c3, c0, 0
 103         instr_sync
 104         .endif
 105         .endm
 106 
 107         /* Restore the user access state previously saved by uaccess_entry */
 108         .macro  uaccess_exit, tsk, tmp0, tmp1
 109         ldr     \tmp1, [sp, #SVC_ADDR_LIMIT]
 110  DACR(  ldr     \tmp0, [sp, #SVC_DACR])
 111         str     \tmp1, [\tsk, #TI_ADDR_LIMIT]
 112  DACR(  mcr     p15, 0, \tmp0, c3, c0, 0)
 113         .endm
 114 
 115 #undef DACR
 116 
 117 #endif /* __ASM_UACCESS_ASM_H__ */

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