0001
0002
0003 #ifndef __ASM_UACCESS_ASM_H__
0004 #define __ASM_UACCESS_ASM_H__
0005
0006 #include <asm/asm-offsets.h>
0007 #include <asm/domain.h>
0008 #include <asm/memory.h>
0009 #include <asm/thread_info.h>
0010
0011 .macro csdb
0012 #ifdef CONFIG_THUMB2_KERNEL
0013 .inst.w 0xf3af8014
0014 #else
0015 .inst 0xe320f014
0016 #endif
0017 .endm
0018
0019 .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
0020 #ifndef CONFIG_CPU_USE_DOMAINS
0021 adds \tmp, \addr, #\size - 1
0022 sbcscc \tmp, \tmp, \limit
0023 bcs \bad
0024 #ifdef CONFIG_CPU_SPECTRE
0025 movcs \addr, #0
0026 csdb
0027 #endif
0028 #endif
0029 .endm
0030
0031 .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
0032 #ifdef CONFIG_CPU_SPECTRE
0033 sub \tmp, \limit, #1
0034 subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr
0035 addhs \tmp, \tmp, #1 @ if (tmp >= 0) {
0036 subshs \tmp, \tmp, \size @ tmp = limit - (addr + size) }
0037 movlo \addr, #0 @ if (tmp < 0) addr = NULL
0038 csdb
0039 #endif
0040 .endm
0041
0042 .macro uaccess_disable, tmp, isb=1
0043 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
0044
0045
0046
0047
0048 mov \tmp, #DACR_UACCESS_DISABLE
0049 mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register
0050 .if \isb
0051 instr_sync
0052 .endif
0053 #endif
0054 .endm
0055
0056 .macro uaccess_enable, tmp, isb=1
0057 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
0058
0059
0060
0061
0062 mov \tmp, #DACR_UACCESS_ENABLE
0063 mcr p15, 0, \tmp, c3, c0, 0
0064 .if \isb
0065 instr_sync
0066 .endif
0067 #endif
0068 .endm
0069
0070 #if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS)
0071 #define DACR(x...) x
0072 #else
0073 #define DACR(x...)
0074 #endif
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable
0087 DACR( mrc p15, 0, \tmp0, c3, c0, 0)
0088 DACR( str \tmp0, [sp, #SVC_DACR])
0089 .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN)
0090
0091 mov \tmp2, #DACR_UACCESS_DISABLE
0092 mcr p15, 0, \tmp2, c3, c0, 0
0093 instr_sync
0094 .elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS)
0095
0096 bic \tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL)
0097 orr \tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT)
0098 mcr p15, 0, \tmp2, c3, c0, 0
0099 instr_sync
0100 .endif
0101 .endm
0102
0103
0104 .macro uaccess_exit, tsk, tmp0, tmp1
0105 DACR( ldr \tmp0, [sp, #SVC_DACR])
0106 DACR( mcr p15, 0, \tmp0, c3, c0, 0)
0107 .endm
0108
0109 #undef DACR
0110
0111 #endif