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

getuser.S (4620B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * __get_user functions.
      4 *
      5 * (C) Copyright 1998 Linus Torvalds
      6 * (C) Copyright 2005 Andi Kleen
      7 * (C) Copyright 2008 Glauber Costa
      8 *
      9 * These functions have a non-standard call interface
     10 * to make them more efficient, especially as they
     11 * return an error value in addition to the "real"
     12 * return value.
     13 */
     14
     15/*
     16 * __get_user_X
     17 *
     18 * Inputs:	%[r|e]ax contains the address.
     19 *
     20 * Outputs:	%[r|e]ax is error code (0 or -EFAULT)
     21 *		%[r|e]dx contains zero-extended value
     22 *		%ecx contains the high half for 32-bit __get_user_8
     23 *
     24 *
     25 * These functions should not modify any other registers,
     26 * as they get called from within inline assembly.
     27 */
     28
     29#include <linux/linkage.h>
     30#include <asm/page_types.h>
     31#include <asm/errno.h>
     32#include <asm/asm-offsets.h>
     33#include <asm/thread_info.h>
     34#include <asm/asm.h>
     35#include <asm/smap.h>
     36#include <asm/export.h>
     37
     38#define ASM_BARRIER_NOSPEC ALTERNATIVE "", "lfence", X86_FEATURE_LFENCE_RDTSC
     39
     40#ifdef CONFIG_X86_5LEVEL
     41#define LOAD_TASK_SIZE_MINUS_N(n) \
     42	ALTERNATIVE __stringify(mov $((1 << 47) - 4096 - (n)),%rdx), \
     43		    __stringify(mov $((1 << 56) - 4096 - (n)),%rdx), X86_FEATURE_LA57
     44#else
     45#define LOAD_TASK_SIZE_MINUS_N(n) \
     46	mov $(TASK_SIZE_MAX - (n)),%_ASM_DX
     47#endif
     48
     49	.text
     50SYM_FUNC_START(__get_user_1)
     51	LOAD_TASK_SIZE_MINUS_N(0)
     52	cmp %_ASM_DX,%_ASM_AX
     53	jae bad_get_user
     54	sbb %_ASM_DX, %_ASM_DX		/* array_index_mask_nospec() */
     55	and %_ASM_DX, %_ASM_AX
     56	ASM_STAC
     571:	movzbl (%_ASM_AX),%edx
     58	xor %eax,%eax
     59	ASM_CLAC
     60	RET
     61SYM_FUNC_END(__get_user_1)
     62EXPORT_SYMBOL(__get_user_1)
     63
     64SYM_FUNC_START(__get_user_2)
     65	LOAD_TASK_SIZE_MINUS_N(1)
     66	cmp %_ASM_DX,%_ASM_AX
     67	jae bad_get_user
     68	sbb %_ASM_DX, %_ASM_DX		/* array_index_mask_nospec() */
     69	and %_ASM_DX, %_ASM_AX
     70	ASM_STAC
     712:	movzwl (%_ASM_AX),%edx
     72	xor %eax,%eax
     73	ASM_CLAC
     74	RET
     75SYM_FUNC_END(__get_user_2)
     76EXPORT_SYMBOL(__get_user_2)
     77
     78SYM_FUNC_START(__get_user_4)
     79	LOAD_TASK_SIZE_MINUS_N(3)
     80	cmp %_ASM_DX,%_ASM_AX
     81	jae bad_get_user
     82	sbb %_ASM_DX, %_ASM_DX		/* array_index_mask_nospec() */
     83	and %_ASM_DX, %_ASM_AX
     84	ASM_STAC
     853:	movl (%_ASM_AX),%edx
     86	xor %eax,%eax
     87	ASM_CLAC
     88	RET
     89SYM_FUNC_END(__get_user_4)
     90EXPORT_SYMBOL(__get_user_4)
     91
     92SYM_FUNC_START(__get_user_8)
     93#ifdef CONFIG_X86_64
     94	LOAD_TASK_SIZE_MINUS_N(7)
     95	cmp %_ASM_DX,%_ASM_AX
     96	jae bad_get_user
     97	sbb %_ASM_DX, %_ASM_DX		/* array_index_mask_nospec() */
     98	and %_ASM_DX, %_ASM_AX
     99	ASM_STAC
    1004:	movq (%_ASM_AX),%rdx
    101	xor %eax,%eax
    102	ASM_CLAC
    103	RET
    104#else
    105	LOAD_TASK_SIZE_MINUS_N(7)
    106	cmp %_ASM_DX,%_ASM_AX
    107	jae bad_get_user_8
    108	sbb %_ASM_DX, %_ASM_DX		/* array_index_mask_nospec() */
    109	and %_ASM_DX, %_ASM_AX
    110	ASM_STAC
    1114:	movl (%_ASM_AX),%edx
    1125:	movl 4(%_ASM_AX),%ecx
    113	xor %eax,%eax
    114	ASM_CLAC
    115	RET
    116#endif
    117SYM_FUNC_END(__get_user_8)
    118EXPORT_SYMBOL(__get_user_8)
    119
    120/* .. and the same for __get_user, just without the range checks */
    121SYM_FUNC_START(__get_user_nocheck_1)
    122	ASM_STAC
    123	ASM_BARRIER_NOSPEC
    1246:	movzbl (%_ASM_AX),%edx
    125	xor %eax,%eax
    126	ASM_CLAC
    127	RET
    128SYM_FUNC_END(__get_user_nocheck_1)
    129EXPORT_SYMBOL(__get_user_nocheck_1)
    130
    131SYM_FUNC_START(__get_user_nocheck_2)
    132	ASM_STAC
    133	ASM_BARRIER_NOSPEC
    1347:	movzwl (%_ASM_AX),%edx
    135	xor %eax,%eax
    136	ASM_CLAC
    137	RET
    138SYM_FUNC_END(__get_user_nocheck_2)
    139EXPORT_SYMBOL(__get_user_nocheck_2)
    140
    141SYM_FUNC_START(__get_user_nocheck_4)
    142	ASM_STAC
    143	ASM_BARRIER_NOSPEC
    1448:	movl (%_ASM_AX),%edx
    145	xor %eax,%eax
    146	ASM_CLAC
    147	RET
    148SYM_FUNC_END(__get_user_nocheck_4)
    149EXPORT_SYMBOL(__get_user_nocheck_4)
    150
    151SYM_FUNC_START(__get_user_nocheck_8)
    152	ASM_STAC
    153	ASM_BARRIER_NOSPEC
    154#ifdef CONFIG_X86_64
    1559:	movq (%_ASM_AX),%rdx
    156#else
    1579:	movl (%_ASM_AX),%edx
    15810:	movl 4(%_ASM_AX),%ecx
    159#endif
    160	xor %eax,%eax
    161	ASM_CLAC
    162	RET
    163SYM_FUNC_END(__get_user_nocheck_8)
    164EXPORT_SYMBOL(__get_user_nocheck_8)
    165
    166
    167SYM_CODE_START_LOCAL(.Lbad_get_user_clac)
    168	ASM_CLAC
    169bad_get_user:
    170	xor %edx,%edx
    171	mov $(-EFAULT),%_ASM_AX
    172	RET
    173SYM_CODE_END(.Lbad_get_user_clac)
    174
    175#ifdef CONFIG_X86_32
    176SYM_CODE_START_LOCAL(.Lbad_get_user_8_clac)
    177	ASM_CLAC
    178bad_get_user_8:
    179	xor %edx,%edx
    180	xor %ecx,%ecx
    181	mov $(-EFAULT),%_ASM_AX
    182	RET
    183SYM_CODE_END(.Lbad_get_user_8_clac)
    184#endif
    185
    186/* get_user */
    187	_ASM_EXTABLE_UA(1b, .Lbad_get_user_clac)
    188	_ASM_EXTABLE_UA(2b, .Lbad_get_user_clac)
    189	_ASM_EXTABLE_UA(3b, .Lbad_get_user_clac)
    190#ifdef CONFIG_X86_64
    191	_ASM_EXTABLE_UA(4b, .Lbad_get_user_clac)
    192#else
    193	_ASM_EXTABLE_UA(4b, .Lbad_get_user_8_clac)
    194	_ASM_EXTABLE_UA(5b, .Lbad_get_user_8_clac)
    195#endif
    196
    197/* __get_user */
    198	_ASM_EXTABLE_UA(6b, .Lbad_get_user_clac)
    199	_ASM_EXTABLE_UA(7b, .Lbad_get_user_clac)
    200	_ASM_EXTABLE_UA(8b, .Lbad_get_user_clac)
    201#ifdef CONFIG_X86_64
    202	_ASM_EXTABLE_UA(9b, .Lbad_get_user_clac)
    203#else
    204	_ASM_EXTABLE_UA(9b, .Lbad_get_user_8_clac)
    205	_ASM_EXTABLE_UA(10b, .Lbad_get_user_8_clac)
    206#endif