linux/arch/s390/include/asm/extable.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __S390_EXTABLE_H
   3#define __S390_EXTABLE_H
   4
   5#include <asm/ptrace.h>
   6#include <linux/compiler.h>
   7
   8/*
   9 * The exception table consists of three addresses:
  10 *
  11 * - Address of an instruction that is allowed to fault.
  12 * - Address at which the program should continue.
  13 * - Optional address of handler that takes pt_regs * argument and runs in
  14 *   interrupt context.
  15 *
  16 * No registers are modified, so it is entirely up to the continuation code
  17 * to figure out what to do.
  18 *
  19 * All the routines below use bits of fixup code that are out of line
  20 * with the main instruction path.  This means when everything is well,
  21 * we don't even have to jump over them.  Further, they do not intrude
  22 * on our cache or tlb entries.
  23 */
  24
  25struct exception_table_entry
  26{
  27        int insn, fixup;
  28        long handler;
  29};
  30
  31extern struct exception_table_entry *__start_dma_ex_table;
  32extern struct exception_table_entry *__stop_dma_ex_table;
  33
  34const struct exception_table_entry *s390_search_extables(unsigned long addr);
  35
  36static inline unsigned long extable_fixup(const struct exception_table_entry *x)
  37{
  38        return (unsigned long)&x->fixup + x->fixup;
  39}
  40
  41typedef bool (*ex_handler_t)(const struct exception_table_entry *,
  42                             struct pt_regs *);
  43
  44static inline ex_handler_t
  45ex_fixup_handler(const struct exception_table_entry *x)
  46{
  47        if (likely(!x->handler))
  48                return NULL;
  49        return (ex_handler_t)((unsigned long)&x->handler + x->handler);
  50}
  51
  52static inline bool ex_handle(const struct exception_table_entry *x,
  53                             struct pt_regs *regs)
  54{
  55        ex_handler_t handler = ex_fixup_handler(x);
  56
  57        if (unlikely(handler))
  58                return handler(x, regs);
  59        regs->psw.addr = extable_fixup(x);
  60        return true;
  61}
  62
  63#define ARCH_HAS_RELATIVE_EXTABLE
  64
  65static inline void swap_ex_entry_fixup(struct exception_table_entry *a,
  66                                       struct exception_table_entry *b,
  67                                       struct exception_table_entry tmp,
  68                                       int delta)
  69{
  70        a->fixup = b->fixup + delta;
  71        b->fixup = tmp.fixup - delta;
  72        a->handler = b->handler + delta;
  73        b->handler = tmp.handler - delta;
  74}
  75
  76#endif
  77