linux/arch/powerpc/include/asm/hw_breakpoint.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * PowerPC BookIII S hardware breakpoint definitions
   4 *
   5 * Copyright 2010, IBM Corporation.
   6 * Author: K.Prasad <prasad@linux.vnet.ibm.com>
   7 */
   8
   9#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
  10#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
  11
  12#include <asm/cpu_has_feature.h>
  13
  14#ifdef  __KERNEL__
  15struct arch_hw_breakpoint {
  16        unsigned long   address;
  17        u16             type;
  18        u16             len; /* length of the target data symbol */
  19        u16             hw_len; /* length programmed in hw */
  20        u8              flags;
  21};
  22
  23/* Note: Don't change the first 6 bits below as they are in the same order
  24 * as the dabr and dabrx.
  25 */
  26#define HW_BRK_TYPE_READ                0x01
  27#define HW_BRK_TYPE_WRITE               0x02
  28#define HW_BRK_TYPE_TRANSLATE           0x04
  29#define HW_BRK_TYPE_USER                0x08
  30#define HW_BRK_TYPE_KERNEL              0x10
  31#define HW_BRK_TYPE_HYP                 0x20
  32#define HW_BRK_TYPE_EXTRANEOUS_IRQ      0x80
  33
  34/* bits that overlap with the bottom 3 bits of the dabr */
  35#define HW_BRK_TYPE_RDWR        (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)
  36#define HW_BRK_TYPE_DABR        (HW_BRK_TYPE_RDWR | HW_BRK_TYPE_TRANSLATE)
  37#define HW_BRK_TYPE_PRIV_ALL    (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
  38                                 HW_BRK_TYPE_HYP)
  39
  40#define HW_BRK_FLAG_DISABLED    0x1
  41
  42/* Minimum granularity */
  43#ifdef CONFIG_PPC_8xx
  44#define HW_BREAKPOINT_SIZE  0x4
  45#else
  46#define HW_BREAKPOINT_SIZE  0x8
  47#endif
  48#define HW_BREAKPOINT_SIZE_QUADWORD     0x10
  49
  50#define DABR_MAX_LEN    8
  51#define DAWR_MAX_LEN    512
  52
  53static inline int nr_wp_slots(void)
  54{
  55        return cpu_has_feature(CPU_FTR_DAWR1) ? 2 : 1;
  56}
  57
  58bool wp_check_constraints(struct pt_regs *regs, ppc_inst_t instr,
  59                          unsigned long ea, int type, int size,
  60                          struct arch_hw_breakpoint *info);
  61
  62void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
  63                         int *type, int *size, unsigned long *ea);
  64
  65#ifdef CONFIG_HAVE_HW_BREAKPOINT
  66#include <linux/kdebug.h>
  67#include <asm/reg.h>
  68#include <asm/debug.h>
  69
  70struct perf_event_attr;
  71struct perf_event;
  72struct pmu;
  73struct perf_sample_data;
  74struct task_struct;
  75
  76extern int hw_breakpoint_slots(int type);
  77extern int arch_bp_generic_fields(int type, int *gen_bp_type);
  78extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
  79extern int hw_breakpoint_arch_parse(struct perf_event *bp,
  80                                    const struct perf_event_attr *attr,
  81                                    struct arch_hw_breakpoint *hw);
  82extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
  83                                                unsigned long val, void *data);
  84int arch_install_hw_breakpoint(struct perf_event *bp);
  85void arch_uninstall_hw_breakpoint(struct perf_event *bp);
  86void hw_breakpoint_pmu_read(struct perf_event *bp);
  87extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
  88
  89extern struct pmu perf_ops_bp;
  90extern void ptrace_triggered(struct perf_event *bp,
  91                        struct perf_sample_data *data, struct pt_regs *regs);
  92static inline void hw_breakpoint_disable(void)
  93{
  94        int i;
  95        struct arch_hw_breakpoint null_brk = {0};
  96
  97        if (!ppc_breakpoint_available())
  98                return;
  99
 100        for (i = 0; i < nr_wp_slots(); i++)
 101                __set_breakpoint(i, &null_brk);
 102}
 103extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 104int hw_breakpoint_handler(struct die_args *args);
 105
 106#else   /* CONFIG_HAVE_HW_BREAKPOINT */
 107static inline void hw_breakpoint_disable(void) { }
 108static inline void thread_change_pc(struct task_struct *tsk,
 109                                        struct pt_regs *regs) { }
 110
 111#endif  /* CONFIG_HAVE_HW_BREAKPOINT */
 112
 113
 114#ifdef CONFIG_PPC_DAWR
 115extern bool dawr_force_enable;
 116static inline bool dawr_enabled(void)
 117{
 118        return dawr_force_enable;
 119}
 120int set_dawr(int nr, struct arch_hw_breakpoint *brk);
 121#else
 122static inline bool dawr_enabled(void) { return false; }
 123static inline int set_dawr(int nr, struct arch_hw_breakpoint *brk) { return -1; }
 124#endif
 125
 126#endif  /* __KERNEL__ */
 127#endif  /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
 128