mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-27 09:02:25 -04:00
Remove EX_TABLE_UA_LOAD_MEM exception handling and replace it with EX_TABLE_UA_FAULT. Open code the return code check, and also open code setting of the destination to zero in case of an error. In almost all cases the compiler is able to optimize the open coded checks away, since all users of get_users() must check the return code, and are not supposed to use the result in case of an error. In addition this allows to change the get_user() inline assembly so that the "Q" constraint can be used for the destination, instead of only an "a" constraint. This generates slightly better code. Acked-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
88 lines
3.3 KiB
C
88 lines
3.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __ASM_EXTABLE_H
|
|
#define __ASM_EXTABLE_H
|
|
|
|
#include <linux/stringify.h>
|
|
#include <linux/bits.h>
|
|
#include <asm/asm-const.h>
|
|
|
|
#define EX_TYPE_NONE 0
|
|
#define EX_TYPE_FIXUP 1
|
|
#define EX_TYPE_BPF 2
|
|
#define EX_TYPE_UA_FAULT 3
|
|
#define EX_TYPE_UA_LOAD_REG 5
|
|
#define EX_TYPE_UA_LOAD_REGPAIR 6
|
|
#define EX_TYPE_ZEROPAD 7
|
|
#define EX_TYPE_FPC 8
|
|
|
|
#define EX_DATA_REG_ERR_SHIFT 0
|
|
#define EX_DATA_REG_ERR GENMASK(3, 0)
|
|
|
|
#define EX_DATA_REG_ADDR_SHIFT 4
|
|
#define EX_DATA_REG_ADDR GENMASK(7, 4)
|
|
|
|
#define EX_DATA_LEN_SHIFT 8
|
|
#define EX_DATA_LEN GENMASK(11, 8)
|
|
|
|
#define __EX_TABLE(_section, _fault, _target, _type, _regerr, _regaddr, _len) \
|
|
stringify_in_c(.section _section,"a";) \
|
|
stringify_in_c(.balign 4;) \
|
|
stringify_in_c(.long (_fault) - .;) \
|
|
stringify_in_c(.long (_target) - .;) \
|
|
stringify_in_c(.short (_type);) \
|
|
stringify_in_c(.macro extable_reg regerr, regaddr;) \
|
|
stringify_in_c(.set .Lfound, 0;) \
|
|
stringify_in_c(.set .Lcurr, 0;) \
|
|
stringify_in_c(.irp rs,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;) \
|
|
stringify_in_c( .ifc "\regerr", "%%r\rs";) \
|
|
stringify_in_c( .set .Lfound, 1;) \
|
|
stringify_in_c( .set .Lregerr, .Lcurr;) \
|
|
stringify_in_c( .endif;) \
|
|
stringify_in_c( .set .Lcurr, .Lcurr+1;) \
|
|
stringify_in_c(.endr;) \
|
|
stringify_in_c(.ifne (.Lfound != 1);) \
|
|
stringify_in_c( .error "extable_reg: bad register argument1";) \
|
|
stringify_in_c(.endif;) \
|
|
stringify_in_c(.set .Lfound, 0;) \
|
|
stringify_in_c(.set .Lcurr, 0;) \
|
|
stringify_in_c(.irp rs,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;) \
|
|
stringify_in_c( .ifc "\regaddr", "%%r\rs";) \
|
|
stringify_in_c( .set .Lfound, 1;) \
|
|
stringify_in_c( .set .Lregaddr, .Lcurr;) \
|
|
stringify_in_c( .endif;) \
|
|
stringify_in_c( .set .Lcurr, .Lcurr+1;) \
|
|
stringify_in_c(.endr;) \
|
|
stringify_in_c(.ifne (.Lfound != 1);) \
|
|
stringify_in_c( .error "extable_reg: bad register argument2";) \
|
|
stringify_in_c(.endif;) \
|
|
stringify_in_c(.short .Lregerr << EX_DATA_REG_ERR_SHIFT | \
|
|
.Lregaddr << EX_DATA_REG_ADDR_SHIFT | \
|
|
_len << EX_DATA_LEN_SHIFT;) \
|
|
stringify_in_c(.endm;) \
|
|
stringify_in_c(extable_reg _regerr,_regaddr;) \
|
|
stringify_in_c(.purgem extable_reg;) \
|
|
stringify_in_c(.previous)
|
|
|
|
#define EX_TABLE(_fault, _target) \
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FIXUP, __stringify(%%r0), __stringify(%%r0), 0)
|
|
|
|
#define EX_TABLE_AMODE31(_fault, _target) \
|
|
__EX_TABLE(.amode31.ex_table, _fault, _target, EX_TYPE_FIXUP, __stringify(%%r0), __stringify(%%r0), 0)
|
|
|
|
#define EX_TABLE_UA_FAULT(_fault, _target, _regerr) \
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_FAULT, _regerr, _regerr, 0)
|
|
|
|
#define EX_TABLE_UA_LOAD_REG(_fault, _target, _regerr, _regzero) \
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_LOAD_REG, _regerr, _regzero, 0)
|
|
|
|
#define EX_TABLE_UA_LOAD_REGPAIR(_fault, _target, _regerr, _regzero) \
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_LOAD_REGPAIR, _regerr, _regzero, 0)
|
|
|
|
#define EX_TABLE_ZEROPAD(_fault, _target, _regdata, _regaddr) \
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_ZEROPAD, _regdata, _regaddr, 0)
|
|
|
|
#define EX_TABLE_FPC(_fault, _target) \
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FPC, __stringify(%%r0), __stringify(%%r0), 0)
|
|
|
|
#endif /* __ASM_EXTABLE_H */
|