cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

uaccess-asm.h (2703B)


      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 DACR(	mrc	p15, 0, \tmp0, c3, c0, 0)
     88 DACR(	str	\tmp0, [sp, #SVC_DACR])
     89	.if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN)
     90	/* kernel=client, user=no access */
     91	mov	\tmp2, #DACR_UACCESS_DISABLE
     92	mcr	p15, 0, \tmp2, c3, c0, 0
     93	instr_sync
     94	.elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS)
     95	/* kernel=client */
     96	bic	\tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL)
     97	orr	\tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT)
     98	mcr	p15, 0, \tmp2, c3, c0, 0
     99	instr_sync
    100	.endif
    101	.endm
    102
    103	/* Restore the user access state previously saved by uaccess_entry */
    104	.macro	uaccess_exit, tsk, tmp0, tmp1
    105 DACR(	ldr	\tmp0, [sp, #SVC_DACR])
    106 DACR(	mcr	p15, 0, \tmp0, c3, c0, 0)
    107	.endm
    108
    109#undef DACR
    110
    111#endif /* __ASM_UACCESS_ASM_H__ */