2022-02-28 11:22:12 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef __ASM_EXTABLE_H
|
|
|
|
#define __ASM_EXTABLE_H
|
|
|
|
|
|
|
|
#include <linux/stringify.h>
|
2022-05-01 21:26:06 +02:00
|
|
|
#include <linux/bits.h>
|
2022-02-28 11:22:12 +01:00
|
|
|
#include <asm/asm-const.h>
|
|
|
|
|
2022-05-01 21:26:06 +02:00
|
|
|
#define EX_TYPE_NONE 0
|
|
|
|
#define EX_TYPE_FIXUP 1
|
|
|
|
#define EX_TYPE_BPF 2
|
|
|
|
#define EX_TYPE_UA_STORE 3
|
|
|
|
#define EX_TYPE_UA_LOAD_MEM 4
|
|
|
|
#define EX_TYPE_UA_LOAD_REG 5
|
2022-11-02 15:18:45 +01:00
|
|
|
#define EX_TYPE_UA_LOAD_REGPAIR 6
|
2023-10-06 15:42:42 +02:00
|
|
|
#define EX_TYPE_ZEROPAD 7
|
2022-05-01 21:26:06 +02:00
|
|
|
|
|
|
|
#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)
|
2022-02-28 14:52:42 +01:00
|
|
|
|
2023-10-06 15:42:40 +02:00
|
|
|
#define __EX_TABLE(_section, _fault, _target, _type, _regerr, _regaddr, _len) \
|
2022-05-01 21:26:06 +02:00
|
|
|
stringify_in_c(.section _section,"a";) \
|
2023-06-22 13:24:40 +02:00
|
|
|
stringify_in_c(.balign 4;) \
|
2022-05-01 21:26:06 +02:00
|
|
|
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;) \
|
s390/extable: add dedicated uaccess handler
This is more or less a combination of commit 2e77a62cb3a6 ("arm64:
extable: add a dedicated uaccess handler") and commit 4b5305decc84
("x86/extable: Extend extable functionality").
To describe the problem that needs to solved let's cite the full arm64
commit message:
------
For inline assembly, we place exception fixups out-of-line in the
`.fixup` section such that these are out of the way of the fast path.
This has a few drawbacks:
* Since the fixup code is anonymous, backtraces will symbolize fixups
as offsets from the nearest prior symbol, currently
`__entry_tramp_text_end`. This is confusing, and painful to debug
without access to the relevant vmlinux.
* Since the exception handler adjusts the PC to execute the fixup, and
the fixup uses a direct branch back into the function it fixes,
backtraces of fixups miss the original function. This is confusing,
and violates requirements for RELIABLE_STACKTRACE (and therefore
LIVEPATCH).
* Inline assembly and associated fixups are generated from templates,
and we have many copies of logically identical fixups which only
differ in which specific registers are written to and which address
is branched to at the end of the fixup. This is potentially wasteful
of I-cache resources, and makes it hard to add additional logic to
fixups without significant bloat.
This patch address all three concerns for inline uaccess fixups by
adding a dedicated exception handler which updates registers in
exception context and subsequent returns back into the function which
faulted, removing the need for fixups specialized to each faulting
instruction.
Other than backtracing, there should be no functional change as a result
of this patch.
------
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2022-02-28 15:02:46 +01:00
|
|
|
stringify_in_c(.previous)
|
|
|
|
|
2022-02-28 11:22:12 +01:00
|
|
|
#define EX_TABLE(_fault, _target) \
|
2023-10-06 15:42:40 +02:00
|
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FIXUP, __stringify(%%r0), __stringify(%%r0), 0)
|
2022-05-01 21:26:06 +02:00
|
|
|
|
2022-02-28 11:22:12 +01:00
|
|
|
#define EX_TABLE_AMODE31(_fault, _target) \
|
2023-10-06 15:42:40 +02:00
|
|
|
__EX_TABLE(.amode31.ex_table, _fault, _target, EX_TYPE_FIXUP, __stringify(%%r0), __stringify(%%r0), 0)
|
2022-05-01 21:26:06 +02:00
|
|
|
|
|
|
|
#define EX_TABLE_UA_STORE(_fault, _target, _regerr) \
|
2023-10-06 15:42:40 +02:00
|
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_STORE, _regerr, _regerr, 0)
|
2022-05-01 21:26:06 +02:00
|
|
|
|
|
|
|
#define EX_TABLE_UA_LOAD_MEM(_fault, _target, _regerr, _regmem, _len) \
|
2023-10-06 15:42:40 +02:00
|
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_LOAD_MEM, _regerr, _regmem, _len)
|
2022-05-01 21:26:06 +02:00
|
|
|
|
|
|
|
#define EX_TABLE_UA_LOAD_REG(_fault, _target, _regerr, _regzero) \
|
2023-10-06 15:42:40 +02:00
|
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_LOAD_REG, _regerr, _regzero, 0)
|
2022-02-28 11:22:12 +01:00
|
|
|
|
2022-11-02 15:18:45 +01:00
|
|
|
#define EX_TABLE_UA_LOAD_REGPAIR(_fault, _target, _regerr, _regzero) \
|
2023-10-06 15:42:40 +02:00
|
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_LOAD_REGPAIR, _regerr, _regzero, 0)
|
2022-11-02 15:18:45 +01:00
|
|
|
|
2023-10-06 15:42:42 +02:00
|
|
|
#define EX_TABLE_ZEROPAD(_fault, _target, _regdata, _regaddr) \
|
|
|
|
__EX_TABLE(__ex_table, _fault, _target, EX_TYPE_ZEROPAD, _regdata, _regaddr, 0)
|
|
|
|
|
2022-02-28 11:22:12 +01:00
|
|
|
#endif /* __ASM_EXTABLE_H */
|