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