diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-11-19 06:23:08 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-11-19 06:23:08 -0500 |
commit | c71d4aa7e98f30d4011b44b168263abc72f676bd (patch) | |
tree | 3daa760c738a6e90f8af4b9ff163e608f10884e4 | |
parent | 667832da846b5748e6c7b3139bbe015c7ea189f7 (diff) | |
parent | f600b9fcd2bcb8ee0adb235f54ccdd93c729c442 (diff) |
Merge branch 'hw-breakpoint' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into devel-stable
-rw-r--r-- | arch/arm/include/asm/cti.h | 20 | ||||
-rw-r--r-- | arch/arm/include/asm/hw_breakpoint.h | 8 | ||||
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 154 |
3 files changed, 91 insertions, 91 deletions
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h index a0ada3ea4358..f2e5cad3f306 100644 --- a/arch/arm/include/asm/cti.h +++ b/arch/arm/include/asm/cti.h | |||
@@ -146,15 +146,7 @@ static inline void cti_irq_ack(struct cti *cti) | |||
146 | */ | 146 | */ |
147 | static inline void cti_unlock(struct cti *cti) | 147 | static inline void cti_unlock(struct cti *cti) |
148 | { | 148 | { |
149 | void __iomem *base = cti->base; | 149 | __raw_writel(LOCKCODE, cti->base + LOCKACCESS); |
150 | unsigned long val; | ||
151 | |||
152 | val = __raw_readl(base + LOCKSTATUS); | ||
153 | |||
154 | if (val & 1) { | ||
155 | val = LOCKCODE; | ||
156 | __raw_writel(val, base + LOCKACCESS); | ||
157 | } | ||
158 | } | 150 | } |
159 | 151 | ||
160 | /** | 152 | /** |
@@ -166,14 +158,6 @@ static inline void cti_unlock(struct cti *cti) | |||
166 | */ | 158 | */ |
167 | static inline void cti_lock(struct cti *cti) | 159 | static inline void cti_lock(struct cti *cti) |
168 | { | 160 | { |
169 | void __iomem *base = cti->base; | 161 | __raw_writel(~LOCKCODE, cti->base + LOCKACCESS); |
170 | unsigned long val; | ||
171 | |||
172 | val = __raw_readl(base + LOCKSTATUS); | ||
173 | |||
174 | if (!(val & 1)) { | ||
175 | val = ~LOCKCODE; | ||
176 | __raw_writel(val, base + LOCKACCESS); | ||
177 | } | ||
178 | } | 162 | } |
179 | #endif | 163 | #endif |
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index c190bc992f0e..01169dd723f1 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h | |||
@@ -98,12 +98,12 @@ static inline void decode_ctrl_reg(u32 reg, | |||
98 | #define ARM_BASE_WCR 112 | 98 | #define ARM_BASE_WCR 112 |
99 | 99 | ||
100 | /* Accessor macros for the debug registers. */ | 100 | /* Accessor macros for the debug registers. */ |
101 | #define ARM_DBG_READ(M, OP2, VAL) do {\ | 101 | #define ARM_DBG_READ(N, M, OP2, VAL) do {\ |
102 | asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\ | 102 | asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL));\ |
103 | } while (0) | 103 | } while (0) |
104 | 104 | ||
105 | #define ARM_DBG_WRITE(M, OP2, VAL) do {\ | 105 | #define ARM_DBG_WRITE(N, M, OP2, VAL) do {\ |
106 | asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\ | 106 | asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\ |
107 | } while (0) | 107 | } while (0) |
108 | 108 | ||
109 | struct notifier_block; | 109 | struct notifier_block; |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 281bf3301241..5ff2e77782b1 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -52,14 +52,14 @@ static u8 debug_arch; | |||
52 | /* Maximum supported watchpoint length. */ | 52 | /* Maximum supported watchpoint length. */ |
53 | static u8 max_watchpoint_len; | 53 | static u8 max_watchpoint_len; |
54 | 54 | ||
55 | #define READ_WB_REG_CASE(OP2, M, VAL) \ | 55 | #define READ_WB_REG_CASE(OP2, M, VAL) \ |
56 | case ((OP2 << 4) + M): \ | 56 | case ((OP2 << 4) + M): \ |
57 | ARM_DBG_READ(c ## M, OP2, VAL); \ | 57 | ARM_DBG_READ(c0, c ## M, OP2, VAL); \ |
58 | break | 58 | break |
59 | 59 | ||
60 | #define WRITE_WB_REG_CASE(OP2, M, VAL) \ | 60 | #define WRITE_WB_REG_CASE(OP2, M, VAL) \ |
61 | case ((OP2 << 4) + M): \ | 61 | case ((OP2 << 4) + M): \ |
62 | ARM_DBG_WRITE(c ## M, OP2, VAL);\ | 62 | ARM_DBG_WRITE(c0, c ## M, OP2, VAL); \ |
63 | break | 63 | break |
64 | 64 | ||
65 | #define GEN_READ_WB_REG_CASES(OP2, VAL) \ | 65 | #define GEN_READ_WB_REG_CASES(OP2, VAL) \ |
@@ -136,12 +136,12 @@ static u8 get_debug_arch(void) | |||
136 | 136 | ||
137 | /* Do we implement the extended CPUID interface? */ | 137 | /* Do we implement the extended CPUID interface? */ |
138 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | 138 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { |
139 | pr_warning("CPUID feature registers not supported. " | 139 | pr_warn_once("CPUID feature registers not supported. " |
140 | "Assuming v6 debug is present.\n"); | 140 | "Assuming v6 debug is present.\n"); |
141 | return ARM_DEBUG_ARCH_V6; | 141 | return ARM_DEBUG_ARCH_V6; |
142 | } | 142 | } |
143 | 143 | ||
144 | ARM_DBG_READ(c0, 0, didr); | 144 | ARM_DBG_READ(c0, c0, 0, didr); |
145 | return (didr >> 16) & 0xf; | 145 | return (didr >> 16) & 0xf; |
146 | } | 146 | } |
147 | 147 | ||
@@ -169,7 +169,7 @@ static int debug_exception_updates_fsr(void) | |||
169 | static int get_num_wrp_resources(void) | 169 | static int get_num_wrp_resources(void) |
170 | { | 170 | { |
171 | u32 didr; | 171 | u32 didr; |
172 | ARM_DBG_READ(c0, 0, didr); | 172 | ARM_DBG_READ(c0, c0, 0, didr); |
173 | return ((didr >> 28) & 0xf) + 1; | 173 | return ((didr >> 28) & 0xf) + 1; |
174 | } | 174 | } |
175 | 175 | ||
@@ -177,7 +177,7 @@ static int get_num_wrp_resources(void) | |||
177 | static int get_num_brp_resources(void) | 177 | static int get_num_brp_resources(void) |
178 | { | 178 | { |
179 | u32 didr; | 179 | u32 didr; |
180 | ARM_DBG_READ(c0, 0, didr); | 180 | ARM_DBG_READ(c0, c0, 0, didr); |
181 | return ((didr >> 24) & 0xf) + 1; | 181 | return ((didr >> 24) & 0xf) + 1; |
182 | } | 182 | } |
183 | 183 | ||
@@ -228,19 +228,17 @@ static int get_num_brps(void) | |||
228 | * be put into halting debug mode at any time by an external debugger | 228 | * be put into halting debug mode at any time by an external debugger |
229 | * but there is nothing we can do to prevent that. | 229 | * but there is nothing we can do to prevent that. |
230 | */ | 230 | */ |
231 | static int enable_monitor_mode(void) | 231 | static int monitor_mode_enabled(void) |
232 | { | 232 | { |
233 | u32 dscr; | 233 | u32 dscr; |
234 | int ret = 0; | 234 | ARM_DBG_READ(c0, c1, 0, dscr); |
235 | 235 | return !!(dscr & ARM_DSCR_MDBGEN); | |
236 | ARM_DBG_READ(c1, 0, dscr); | 236 | } |
237 | 237 | ||
238 | /* Ensure that halting mode is disabled. */ | 238 | static int enable_monitor_mode(void) |
239 | if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, | 239 | { |
240 | "halting debug mode enabled. Unable to access hardware resources.\n")) { | 240 | u32 dscr; |
241 | ret = -EPERM; | 241 | ARM_DBG_READ(c0, c1, 0, dscr); |
242 | goto out; | ||
243 | } | ||
244 | 242 | ||
245 | /* If monitor mode is already enabled, just return. */ | 243 | /* If monitor mode is already enabled, just return. */ |
246 | if (dscr & ARM_DSCR_MDBGEN) | 244 | if (dscr & ARM_DSCR_MDBGEN) |
@@ -250,24 +248,27 @@ static int enable_monitor_mode(void) | |||
250 | switch (get_debug_arch()) { | 248 | switch (get_debug_arch()) { |
251 | case ARM_DEBUG_ARCH_V6: | 249 | case ARM_DEBUG_ARCH_V6: |
252 | case ARM_DEBUG_ARCH_V6_1: | 250 | case ARM_DEBUG_ARCH_V6_1: |
253 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); | 251 | ARM_DBG_WRITE(c0, c1, 0, (dscr | ARM_DSCR_MDBGEN)); |
254 | break; | 252 | break; |
255 | case ARM_DEBUG_ARCH_V7_ECP14: | 253 | case ARM_DEBUG_ARCH_V7_ECP14: |
256 | case ARM_DEBUG_ARCH_V7_1: | 254 | case ARM_DEBUG_ARCH_V7_1: |
257 | ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); | 255 | ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN)); |
256 | isb(); | ||
258 | break; | 257 | break; |
259 | default: | 258 | default: |
260 | ret = -ENODEV; | 259 | return -ENODEV; |
261 | goto out; | ||
262 | } | 260 | } |
263 | 261 | ||
264 | /* Check that the write made it through. */ | 262 | /* Check that the write made it through. */ |
265 | ARM_DBG_READ(c1, 0, dscr); | 263 | ARM_DBG_READ(c0, c1, 0, dscr); |
266 | if (!(dscr & ARM_DSCR_MDBGEN)) | 264 | if (!(dscr & ARM_DSCR_MDBGEN)) { |
267 | ret = -EPERM; | 265 | pr_warn_once("Failed to enable monitor mode on CPU %d.\n", |
266 | smp_processor_id()); | ||
267 | return -EPERM; | ||
268 | } | ||
268 | 269 | ||
269 | out: | 270 | out: |
270 | return ret; | 271 | return 0; |
271 | } | 272 | } |
272 | 273 | ||
273 | int hw_breakpoint_slots(int type) | 274 | int hw_breakpoint_slots(int type) |
@@ -328,14 +329,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
328 | { | 329 | { |
329 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 330 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
330 | struct perf_event **slot, **slots; | 331 | struct perf_event **slot, **slots; |
331 | int i, max_slots, ctrl_base, val_base, ret = 0; | 332 | int i, max_slots, ctrl_base, val_base; |
332 | u32 addr, ctrl; | 333 | u32 addr, ctrl; |
333 | 334 | ||
334 | /* Ensure that we are in monitor mode and halting mode is disabled. */ | ||
335 | ret = enable_monitor_mode(); | ||
336 | if (ret) | ||
337 | goto out; | ||
338 | |||
339 | addr = info->address; | 335 | addr = info->address; |
340 | ctrl = encode_ctrl_reg(info->ctrl) | 0x1; | 336 | ctrl = encode_ctrl_reg(info->ctrl) | 0x1; |
341 | 337 | ||
@@ -362,9 +358,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
362 | } | 358 | } |
363 | } | 359 | } |
364 | 360 | ||
365 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) { | 361 | if (i == max_slots) { |
366 | ret = -EBUSY; | 362 | pr_warning("Can't find any breakpoint slot\n"); |
367 | goto out; | 363 | return -EBUSY; |
368 | } | 364 | } |
369 | 365 | ||
370 | /* Override the breakpoint data with the step data. */ | 366 | /* Override the breakpoint data with the step data. */ |
@@ -383,9 +379,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
383 | 379 | ||
384 | /* Setup the control register. */ | 380 | /* Setup the control register. */ |
385 | write_wb_reg(ctrl_base + i, ctrl); | 381 | write_wb_reg(ctrl_base + i, ctrl); |
386 | 382 | return 0; | |
387 | out: | ||
388 | return ret; | ||
389 | } | 383 | } |
390 | 384 | ||
391 | void arch_uninstall_hw_breakpoint(struct perf_event *bp) | 385 | void arch_uninstall_hw_breakpoint(struct perf_event *bp) |
@@ -416,8 +410,10 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
416 | } | 410 | } |
417 | } | 411 | } |
418 | 412 | ||
419 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) | 413 | if (i == max_slots) { |
414 | pr_warning("Can't find any breakpoint slot\n"); | ||
420 | return; | 415 | return; |
416 | } | ||
421 | 417 | ||
422 | /* Ensure that we disable the mismatch breakpoint. */ | 418 | /* Ensure that we disable the mismatch breakpoint. */ |
423 | if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE && | 419 | if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE && |
@@ -596,6 +592,10 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
596 | int ret = 0; | 592 | int ret = 0; |
597 | u32 offset, alignment_mask = 0x3; | 593 | u32 offset, alignment_mask = 0x3; |
598 | 594 | ||
595 | /* Ensure that we are in monitor debug mode. */ | ||
596 | if (!monitor_mode_enabled()) | ||
597 | return -ENODEV; | ||
598 | |||
599 | /* Build the arch_hw_breakpoint. */ | 599 | /* Build the arch_hw_breakpoint. */ |
600 | ret = arch_build_bp_info(bp); | 600 | ret = arch_build_bp_info(bp); |
601 | if (ret) | 601 | if (ret) |
@@ -858,7 +858,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
858 | local_irq_enable(); | 858 | local_irq_enable(); |
859 | 859 | ||
860 | /* We only handle watchpoints and hardware breakpoints. */ | 860 | /* We only handle watchpoints and hardware breakpoints. */ |
861 | ARM_DBG_READ(c1, 0, dscr); | 861 | ARM_DBG_READ(c0, c1, 0, dscr); |
862 | 862 | ||
863 | /* Perform perf callbacks. */ | 863 | /* Perform perf callbacks. */ |
864 | switch (ARM_DSCR_MOE(dscr)) { | 864 | switch (ARM_DSCR_MOE(dscr)) { |
@@ -906,7 +906,7 @@ static struct undef_hook debug_reg_hook = { | |||
906 | static void reset_ctrl_regs(void *unused) | 906 | static void reset_ctrl_regs(void *unused) |
907 | { | 907 | { |
908 | int i, raw_num_brps, err = 0, cpu = smp_processor_id(); | 908 | int i, raw_num_brps, err = 0, cpu = smp_processor_id(); |
909 | u32 dbg_power; | 909 | u32 val; |
910 | 910 | ||
911 | /* | 911 | /* |
912 | * v7 debug contains save and restore registers so that debug state | 912 | * v7 debug contains save and restore registers so that debug state |
@@ -919,23 +919,30 @@ static void reset_ctrl_regs(void *unused) | |||
919 | switch (debug_arch) { | 919 | switch (debug_arch) { |
920 | case ARM_DEBUG_ARCH_V6: | 920 | case ARM_DEBUG_ARCH_V6: |
921 | case ARM_DEBUG_ARCH_V6_1: | 921 | case ARM_DEBUG_ARCH_V6_1: |
922 | /* ARMv6 cores just need to reset the registers. */ | 922 | /* ARMv6 cores clear the registers out of reset. */ |
923 | goto reset_regs; | 923 | goto out_mdbgen; |
924 | case ARM_DEBUG_ARCH_V7_ECP14: | 924 | case ARM_DEBUG_ARCH_V7_ECP14: |
925 | /* | 925 | /* |
926 | * Ensure sticky power-down is clear (i.e. debug logic is | 926 | * Ensure sticky power-down is clear (i.e. debug logic is |
927 | * powered up). | 927 | * powered up). |
928 | */ | 928 | */ |
929 | asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); | 929 | ARM_DBG_READ(c1, c5, 4, val); |
930 | if ((dbg_power & 0x1) == 0) | 930 | if ((val & 0x1) == 0) |
931 | err = -EPERM; | 931 | err = -EPERM; |
932 | |||
933 | /* | ||
934 | * Check whether we implement OS save and restore. | ||
935 | */ | ||
936 | ARM_DBG_READ(c1, c1, 4, val); | ||
937 | if ((val & 0x9) == 0) | ||
938 | goto clear_vcr; | ||
932 | break; | 939 | break; |
933 | case ARM_DEBUG_ARCH_V7_1: | 940 | case ARM_DEBUG_ARCH_V7_1: |
934 | /* | 941 | /* |
935 | * Ensure the OS double lock is clear. | 942 | * Ensure the OS double lock is clear. |
936 | */ | 943 | */ |
937 | asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power)); | 944 | ARM_DBG_READ(c1, c3, 4, val); |
938 | if ((dbg_power & 0x1) == 1) | 945 | if ((val & 0x1) == 1) |
939 | err = -EPERM; | 946 | err = -EPERM; |
940 | break; | 947 | break; |
941 | } | 948 | } |
@@ -947,24 +954,29 @@ static void reset_ctrl_regs(void *unused) | |||
947 | } | 954 | } |
948 | 955 | ||
949 | /* | 956 | /* |
950 | * Unconditionally clear the lock by writing a value | 957 | * Unconditionally clear the OS lock by writing a value |
951 | * other than 0xC5ACCE55 to the access register. | 958 | * other than 0xC5ACCE55 to the access register. |
952 | */ | 959 | */ |
953 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); | 960 | ARM_DBG_WRITE(c1, c0, 4, 0); |
954 | isb(); | 961 | isb(); |
955 | 962 | ||
956 | /* | 963 | /* |
957 | * Clear any configured vector-catch events before | 964 | * Clear any configured vector-catch events before |
958 | * enabling monitor mode. | 965 | * enabling monitor mode. |
959 | */ | 966 | */ |
960 | asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); | 967 | clear_vcr: |
968 | ARM_DBG_WRITE(c0, c7, 0, 0); | ||
961 | isb(); | 969 | isb(); |
962 | 970 | ||
963 | reset_regs: | 971 | if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { |
964 | if (enable_monitor_mode()) | 972 | pr_warning("CPU %d failed to disable vector catch\n", cpu); |
965 | return; | 973 | return; |
974 | } | ||
966 | 975 | ||
967 | /* We must also reset any reserved registers. */ | 976 | /* |
977 | * The control/value register pairs are UNKNOWN out of reset so | ||
978 | * clear them to avoid spurious debug events. | ||
979 | */ | ||
968 | raw_num_brps = get_num_brp_resources(); | 980 | raw_num_brps = get_num_brp_resources(); |
969 | for (i = 0; i < raw_num_brps; ++i) { | 981 | for (i = 0; i < raw_num_brps; ++i) { |
970 | write_wb_reg(ARM_BASE_BCR + i, 0UL); | 982 | write_wb_reg(ARM_BASE_BCR + i, 0UL); |
@@ -975,6 +987,19 @@ reset_regs: | |||
975 | write_wb_reg(ARM_BASE_WCR + i, 0UL); | 987 | write_wb_reg(ARM_BASE_WCR + i, 0UL); |
976 | write_wb_reg(ARM_BASE_WVR + i, 0UL); | 988 | write_wb_reg(ARM_BASE_WVR + i, 0UL); |
977 | } | 989 | } |
990 | |||
991 | if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { | ||
992 | pr_warning("CPU %d failed to clear debug register pairs\n", cpu); | ||
993 | return; | ||
994 | } | ||
995 | |||
996 | /* | ||
997 | * Have a crack at enabling monitor mode. We don't actually need | ||
998 | * it yet, but reporting an error early is useful if it fails. | ||
999 | */ | ||
1000 | out_mdbgen: | ||
1001 | if (enable_monitor_mode()) | ||
1002 | cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); | ||
978 | } | 1003 | } |
979 | 1004 | ||
980 | static int __cpuinit dbg_reset_notify(struct notifier_block *self, | 1005 | static int __cpuinit dbg_reset_notify(struct notifier_block *self, |
@@ -992,8 +1017,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { | |||
992 | 1017 | ||
993 | static int __init arch_hw_breakpoint_init(void) | 1018 | static int __init arch_hw_breakpoint_init(void) |
994 | { | 1019 | { |
995 | u32 dscr; | ||
996 | |||
997 | debug_arch = get_debug_arch(); | 1020 | debug_arch = get_debug_arch(); |
998 | 1021 | ||
999 | if (!debug_arch_supported()) { | 1022 | if (!debug_arch_supported()) { |
@@ -1028,17 +1051,10 @@ static int __init arch_hw_breakpoint_init(void) | |||
1028 | core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " : | 1051 | core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " : |
1029 | "", core_num_wrps); | 1052 | "", core_num_wrps); |
1030 | 1053 | ||
1031 | ARM_DBG_READ(c1, 0, dscr); | 1054 | /* Work out the maximum supported watchpoint length. */ |
1032 | if (dscr & ARM_DSCR_HDBGEN) { | 1055 | max_watchpoint_len = get_max_wp_len(); |
1033 | max_watchpoint_len = 4; | 1056 | pr_info("maximum watchpoint size is %u bytes.\n", |
1034 | pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n", | 1057 | max_watchpoint_len); |
1035 | max_watchpoint_len); | ||
1036 | } else { | ||
1037 | /* Work out the maximum supported watchpoint length. */ | ||
1038 | max_watchpoint_len = get_max_wp_len(); | ||
1039 | pr_info("maximum watchpoint size is %u bytes.\n", | ||
1040 | max_watchpoint_len); | ||
1041 | } | ||
1042 | 1058 | ||
1043 | /* Register debug fault handler. */ | 1059 | /* Register debug fault handler. */ |
1044 | hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, | 1060 | hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, |