From e64877dcf5fd05d81fa195785a738f3a729587a3 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 21 Sep 2012 14:53:13 +0100 Subject: ARM: hw_breakpoint: only clear OS lock when implemented on v7 The OS save and restore register are optional in debug architecture v7, so check the status register before attempting to clear the OS lock. Tested-by: Stephen Boyd Signed-off-by: Will Deacon --- arch/arm/kernel/hw_breakpoint.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 281bf3301241..76a650a1a1d7 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -906,7 +906,7 @@ static struct undef_hook debug_reg_hook = { static void reset_ctrl_regs(void *unused) { int i, raw_num_brps, err = 0, cpu = smp_processor_id(); - u32 dbg_power; + u32 val; /* * v7 debug contains save and restore registers so that debug state @@ -926,16 +926,23 @@ static void reset_ctrl_regs(void *unused) * Ensure sticky power-down is clear (i.e. debug logic is * powered up). */ - asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); - if ((dbg_power & 0x1) == 0) + asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (val)); + if ((val & 0x1) == 0) err = -EPERM; + + /* + * Check whether we implement OS save and restore. + */ + asm volatile("mrc p14, 0, %0, c1, c1, 4" : "=r" (val)); + if ((val & 0x9) == 0) + goto clear_vcr; break; case ARM_DEBUG_ARCH_V7_1: /* * Ensure the OS double lock is clear. */ - asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power)); - if ((dbg_power & 0x1) == 1) + asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (val)); + if ((val & 0x1) == 1) err = -EPERM; break; } @@ -947,7 +954,7 @@ static void reset_ctrl_regs(void *unused) } /* - * Unconditionally clear the lock by writing a value + * Unconditionally clear the OS lock by writing a value * other than 0xC5ACCE55 to the access register. */ asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); @@ -957,6 +964,7 @@ static void reset_ctrl_regs(void *unused) * Clear any configured vector-catch events before * enabling monitor mode. */ +clear_vcr: asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); isb(); -- cgit v1.2.1 From b59a540ca927ea84bb0590b9d8076f50c969abb4 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 21 Sep 2012 15:08:17 +0100 Subject: ARM: hw_breakpoint: fix monitor mode detection with v7.1 Detecting whether halting debug is enabled is no longer possible via the DBGDSCR in v7.1, returning an UNKNOWN value for the HDBGen bit via CP14 when the OS lock is clear. This patch removes the halting mode check and ensures that accesses to the internal and external views of the DBGDSCR are serialised with an instruction barrier. Tested-by: Stephen Boyd Signed-off-by: Will Deacon --- arch/arm/kernel/hw_breakpoint.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 76a650a1a1d7..c87ea68d64ae 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -235,13 +235,6 @@ static int enable_monitor_mode(void) ARM_DBG_READ(c1, 0, dscr); - /* Ensure that halting mode is disabled. */ - if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, - "halting debug mode enabled. Unable to access hardware resources.\n")) { - ret = -EPERM; - goto out; - } - /* If monitor mode is already enabled, just return. */ if (dscr & ARM_DSCR_MDBGEN) goto out; @@ -255,6 +248,7 @@ static int enable_monitor_mode(void) case ARM_DEBUG_ARCH_V7_ECP14: case ARM_DEBUG_ARCH_V7_1: ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); + isb(); break; default: ret = -ENODEV; @@ -1000,8 +994,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { static int __init arch_hw_breakpoint_init(void) { - u32 dscr; - debug_arch = get_debug_arch(); if (!debug_arch_supported()) { @@ -1036,17 +1028,10 @@ static int __init arch_hw_breakpoint_init(void) core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " : "", core_num_wrps); - ARM_DBG_READ(c1, 0, dscr); - if (dscr & ARM_DSCR_HDBGEN) { - max_watchpoint_len = 4; - pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n", - max_watchpoint_len); - } else { - /* Work out the maximum supported watchpoint length. */ - max_watchpoint_len = get_max_wp_len(); - pr_info("maximum watchpoint size is %u bytes.\n", - max_watchpoint_len); - } + /* Work out the maximum supported watchpoint length. */ + max_watchpoint_len = get_max_wp_len(); + pr_info("maximum watchpoint size is %u bytes.\n", + max_watchpoint_len); /* Register debug fault handler. */ hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, -- cgit v1.2.1 From 614bea500a88be2a841af0967469961470f2be83 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 21 Sep 2012 15:38:26 +0100 Subject: ARM: hw_breakpoint: fix ordering of debug register reset sequence The debug register reset sequence for v7 and v7.1 is congruent with tap-dancing through a minefield. Rather than wait until we've blown ourselves to pieces, this patch instead checks the debug_err_mask after each potentially faulting operation. We also move the enabling of monitor_mode to the end of the sequence in order to prevent spurious debug events generated by UNKNOWN register values. Reported-by: Stephen Boyd Tested-by: Stephen Boyd Signed-off-by: Will Deacon --- arch/arm/kernel/hw_breakpoint.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index c87ea68d64ae..ae6bf80e3a5e 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -231,8 +231,6 @@ static int get_num_brps(void) static int enable_monitor_mode(void) { u32 dscr; - int ret = 0; - ARM_DBG_READ(c1, 0, dscr); /* If monitor mode is already enabled, just return. */ @@ -251,17 +249,18 @@ static int enable_monitor_mode(void) isb(); break; default: - ret = -ENODEV; - goto out; + return -ENODEV; } /* Check that the write made it through. */ ARM_DBG_READ(c1, 0, dscr); - if (!(dscr & ARM_DSCR_MDBGEN)) - ret = -EPERM; + if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN), + "Failed to enable monitor mode on CPU %d.\n", + smp_processor_id())) + return -EPERM; out: - return ret; + return 0; } int hw_breakpoint_slots(int type) @@ -962,11 +961,16 @@ clear_vcr: asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); isb(); -reset_regs: - if (enable_monitor_mode()) + if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { + pr_warning("CPU %d failed to disable vector catch\n", cpu); return; + } - /* We must also reset any reserved registers. */ +reset_regs: + /* + * The control/value register pairs are UNKNOWN out of reset so + * clear them to avoid spurious debug events. + */ raw_num_brps = get_num_brp_resources(); for (i = 0; i < raw_num_brps; ++i) { write_wb_reg(ARM_BASE_BCR + i, 0UL); @@ -977,6 +981,18 @@ reset_regs: write_wb_reg(ARM_BASE_WCR + i, 0UL); write_wb_reg(ARM_BASE_WVR + i, 0UL); } + + if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { + pr_warning("CPU %d failed to clear debug register pairs\n", cpu); + return; + } + + /* + * Have a crack at enabling monitor mode. We don't actually need + * it yet, but reporting an error early is useful if it fails. + */ + if (enable_monitor_mode()) + cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); } static int __cpuinit dbg_reset_notify(struct notifier_block *self, -- cgit v1.2.1 From 7f4050a07be8ce5fad069722326ccd550577a93a Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 21 Sep 2012 17:53:08 +0100 Subject: ARM: hw_breakpoint: don't try to clear v6 debug registers during boot v6 cores do not provide a way to clear the debug registers without first enabling monitor mode, meaning that we could take spurious debug exceptions. Instead, rely on the registers being in a sane state when we boot as they are defined to be disabled out of reset anyway. Tested-by: Stephen Boyd Signed-off-by: Will Deacon --- arch/arm/kernel/hw_breakpoint.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ae6bf80e3a5e..8cd52faeb77e 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -912,8 +912,8 @@ static void reset_ctrl_regs(void *unused) switch (debug_arch) { case ARM_DEBUG_ARCH_V6: case ARM_DEBUG_ARCH_V6_1: - /* ARMv6 cores just need to reset the registers. */ - goto reset_regs; + /* ARMv6 cores clear the registers out of reset. */ + goto out_mdbgen; case ARM_DEBUG_ARCH_V7_ECP14: /* * Ensure sticky power-down is clear (i.e. debug logic is @@ -966,7 +966,6 @@ clear_vcr: return; } -reset_regs: /* * The control/value register pairs are UNKNOWN out of reset so * clear them to avoid spurious debug events. @@ -991,6 +990,7 @@ reset_regs: * Have a crack at enabling monitor mode. We don't actually need * it yet, but reporting an error early is useful if it fails. */ +out_mdbgen: if (enable_monitor_mode()) cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); } -- cgit v1.2.1 From 5ad29ea24e58777aa1daaa2255670ffb40aefd99 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 21 Sep 2012 18:17:24 +0100 Subject: ARM: hw_breakpoint: make boot quieter without CPUID feature registers Booting on a v6 core without the CPUID feature registers (e.g. 1136) leads to a noisy dmesg complaining about their absence. This patch changes the pr_warning into a pr_warn_once to keep the log quieter. Signed-off-by: Will Deacon --- arch/arm/kernel/hw_breakpoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 8cd52faeb77e..983558eb9023 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -136,8 +136,8 @@ static u8 get_debug_arch(void) /* Do we implement the extended CPUID interface? */ if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { - pr_warning("CPUID feature registers not supported. " - "Assuming v6 debug is present.\n"); + pr_warn_once("CPUID feature registers not supported. " + "Assuming v6 debug is present.\n"); return ARM_DEBUG_ARCH_V6; } -- cgit v1.2.1 From 0daa034e696ac601061cbf60fda41ad39678ae14 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 24 Sep 2012 18:01:13 +0100 Subject: ARM: hw_breakpoint: check if monitor mode is enabled during validation Rather than attempt to enable monitor mode explicitly when scheduling in a breakpoint event (which could raise an undefined exception trap when accessing DBGDSCRext), instead check that DBGDSCRint.MDBGen is set during event validation and report an error to the caller if not. Signed-off-by: Will Deacon --- arch/arm/kernel/hw_breakpoint.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 983558eb9023..8e9532152bd9 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -228,6 +228,13 @@ static int get_num_brps(void) * be put into halting debug mode at any time by an external debugger * but there is nothing we can do to prevent that. */ +static int monitor_mode_enabled(void) +{ + u32 dscr; + ARM_DBG_READ(c1, 0, dscr); + return !!(dscr & ARM_DSCR_MDBGEN); +} + static int enable_monitor_mode(void) { u32 dscr; @@ -321,14 +328,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp) { struct arch_hw_breakpoint *info = counter_arch_bp(bp); struct perf_event **slot, **slots; - int i, max_slots, ctrl_base, val_base, ret = 0; + int i, max_slots, ctrl_base, val_base; u32 addr, ctrl; - /* Ensure that we are in monitor mode and halting mode is disabled. */ - ret = enable_monitor_mode(); - if (ret) - goto out; - addr = info->address; ctrl = encode_ctrl_reg(info->ctrl) | 0x1; @@ -355,10 +357,8 @@ int arch_install_hw_breakpoint(struct perf_event *bp) } } - if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) { - ret = -EBUSY; - goto out; - } + if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) + return -EBUSY; /* Override the breakpoint data with the step data. */ if (info->step_ctrl.enabled) { @@ -376,9 +376,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp) /* Setup the control register. */ write_wb_reg(ctrl_base + i, ctrl); - -out: - return ret; + return 0; } void arch_uninstall_hw_breakpoint(struct perf_event *bp) @@ -589,6 +587,10 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) int ret = 0; u32 offset, alignment_mask = 0x3; + /* Ensure that we are in monitor debug mode. */ + if (!monitor_mode_enabled()) + return -ENODEV; + /* Build the arch_hw_breakpoint. */ ret = arch_build_bp_info(bp); if (ret) -- cgit v1.2.1 From 9e962f76602dbd293a57030f4ce5a4b57853e2ea Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Wed, 26 Sep 2012 17:28:47 +0100 Subject: ARM: hw_breakpoint: use CRn as argument for debug reg accessor macros The coprocessor register CRn for accesses to the debug register can be a different one than C0. Take this into account for the ARM_DBG_READ and the ARM_DBG_WRITE macro. The inline assembler calls which used a coprocessor register CRn other than C0 are replaced by the ARM_DBG_READ or ARM_DBG_WRITE macro. Tested-by: Stephen Boyd Signed-off-by: Dietmar Eggemann Signed-off-by: Will Deacon --- arch/arm/include/asm/hw_breakpoint.h | 8 ++++---- arch/arm/kernel/hw_breakpoint.c | 40 ++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'arch') 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, #define ARM_BASE_WCR 112 /* Accessor macros for the debug registers. */ -#define ARM_DBG_READ(M, OP2, VAL) do {\ - asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\ +#define ARM_DBG_READ(N, M, OP2, VAL) do {\ + asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL));\ } while (0) -#define ARM_DBG_WRITE(M, OP2, VAL) do {\ - asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\ +#define ARM_DBG_WRITE(N, M, OP2, VAL) do {\ + asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\ } while (0) struct notifier_block; diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 8e9532152bd9..05febbaecb44 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -52,14 +52,14 @@ static u8 debug_arch; /* Maximum supported watchpoint length. */ static u8 max_watchpoint_len; -#define READ_WB_REG_CASE(OP2, M, VAL) \ - case ((OP2 << 4) + M): \ - ARM_DBG_READ(c ## M, OP2, VAL); \ +#define READ_WB_REG_CASE(OP2, M, VAL) \ + case ((OP2 << 4) + M): \ + ARM_DBG_READ(c0, c ## M, OP2, VAL); \ break -#define WRITE_WB_REG_CASE(OP2, M, VAL) \ - case ((OP2 << 4) + M): \ - ARM_DBG_WRITE(c ## M, OP2, VAL);\ +#define WRITE_WB_REG_CASE(OP2, M, VAL) \ + case ((OP2 << 4) + M): \ + ARM_DBG_WRITE(c0, c ## M, OP2, VAL); \ break #define GEN_READ_WB_REG_CASES(OP2, VAL) \ @@ -141,7 +141,7 @@ static u8 get_debug_arch(void) return ARM_DEBUG_ARCH_V6; } - ARM_DBG_READ(c0, 0, didr); + ARM_DBG_READ(c0, c0, 0, didr); return (didr >> 16) & 0xf; } @@ -169,7 +169,7 @@ static int debug_exception_updates_fsr(void) static int get_num_wrp_resources(void) { u32 didr; - ARM_DBG_READ(c0, 0, didr); + ARM_DBG_READ(c0, c0, 0, didr); return ((didr >> 28) & 0xf) + 1; } @@ -177,7 +177,7 @@ static int get_num_wrp_resources(void) static int get_num_brp_resources(void) { u32 didr; - ARM_DBG_READ(c0, 0, didr); + ARM_DBG_READ(c0, c0, 0, didr); return ((didr >> 24) & 0xf) + 1; } @@ -231,14 +231,14 @@ static int get_num_brps(void) static int monitor_mode_enabled(void) { u32 dscr; - ARM_DBG_READ(c1, 0, dscr); + ARM_DBG_READ(c0, c1, 0, dscr); return !!(dscr & ARM_DSCR_MDBGEN); } static int enable_monitor_mode(void) { u32 dscr; - ARM_DBG_READ(c1, 0, dscr); + ARM_DBG_READ(c0, c1, 0, dscr); /* If monitor mode is already enabled, just return. */ if (dscr & ARM_DSCR_MDBGEN) @@ -248,11 +248,11 @@ static int enable_monitor_mode(void) switch (get_debug_arch()) { case ARM_DEBUG_ARCH_V6: case ARM_DEBUG_ARCH_V6_1: - ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); + ARM_DBG_WRITE(c0, c1, 0, (dscr | ARM_DSCR_MDBGEN)); break; case ARM_DEBUG_ARCH_V7_ECP14: case ARM_DEBUG_ARCH_V7_1: - ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); + ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN)); isb(); break; default: @@ -260,7 +260,7 @@ static int enable_monitor_mode(void) } /* Check that the write made it through. */ - ARM_DBG_READ(c1, 0, dscr); + ARM_DBG_READ(c0, c1, 0, dscr); if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN), "Failed to enable monitor mode on CPU %d.\n", smp_processor_id())) @@ -853,7 +853,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, local_irq_enable(); /* We only handle watchpoints and hardware breakpoints. */ - ARM_DBG_READ(c1, 0, dscr); + ARM_DBG_READ(c0, c1, 0, dscr); /* Perform perf callbacks. */ switch (ARM_DSCR_MOE(dscr)) { @@ -921,14 +921,14 @@ static void reset_ctrl_regs(void *unused) * Ensure sticky power-down is clear (i.e. debug logic is * powered up). */ - asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (val)); + ARM_DBG_READ(c1, c5, 4, val); if ((val & 0x1) == 0) err = -EPERM; /* * Check whether we implement OS save and restore. */ - asm volatile("mrc p14, 0, %0, c1, c1, 4" : "=r" (val)); + ARM_DBG_READ(c1, c1, 4, val); if ((val & 0x9) == 0) goto clear_vcr; break; @@ -936,7 +936,7 @@ static void reset_ctrl_regs(void *unused) /* * Ensure the OS double lock is clear. */ - asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (val)); + ARM_DBG_READ(c1, c3, 4, val); if ((val & 0x1) == 1) err = -EPERM; break; @@ -952,7 +952,7 @@ static void reset_ctrl_regs(void *unused) * Unconditionally clear the OS lock by writing a value * other than 0xC5ACCE55 to the access register. */ - asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); + ARM_DBG_WRITE(c1, c0, 4, 0); isb(); /* @@ -960,7 +960,7 @@ static void reset_ctrl_regs(void *unused) * enabling monitor mode. */ clear_vcr: - asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); + ARM_DBG_WRITE(c0, c7, 0, 0); isb(); if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { -- cgit v1.2.1 From f435ab79928e4d54082e2838c4562a165e37999c Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 25 Oct 2012 17:18:23 +0100 Subject: ARM: hw_breakpoint: kill WARN_ONCE usage WARN_ONCE is a bit OTT for some of the simple failure cases encountered in hw_breakpoint, so use either pr_warning or pr_warn_once instead. Reported-by: Stephen Boyd Signed-off-by: Will Deacon --- arch/arm/kernel/hw_breakpoint.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 05febbaecb44..5ff2e77782b1 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -261,10 +261,11 @@ static int enable_monitor_mode(void) /* Check that the write made it through. */ ARM_DBG_READ(c0, c1, 0, dscr); - if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN), - "Failed to enable monitor mode on CPU %d.\n", - smp_processor_id())) + if (!(dscr & ARM_DSCR_MDBGEN)) { + pr_warn_once("Failed to enable monitor mode on CPU %d.\n", + smp_processor_id()); return -EPERM; + } out: return 0; @@ -357,8 +358,10 @@ int arch_install_hw_breakpoint(struct perf_event *bp) } } - if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) + if (i == max_slots) { + pr_warning("Can't find any breakpoint slot\n"); return -EBUSY; + } /* Override the breakpoint data with the step data. */ if (info->step_ctrl.enabled) { @@ -407,8 +410,10 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) } } - if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) + if (i == max_slots) { + pr_warning("Can't find any breakpoint slot\n"); return; + } /* Ensure that we disable the mismatch breakpoint. */ if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE && -- cgit v1.2.1 From f600b9fcd2bcb8ee0adb235f54ccdd93c729c442 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 15 Nov 2012 21:28:43 +0000 Subject: ARM: cti: fix manipulation of debug lock registers The LOCKSTATUS register for memory-mapped coresight devices indicates whether or not the device in question implements hardware locking. If not, locking is not present (i.e. LSR.SLI == 0) and LAR is write-ignore, so software doesn't actually need to check the status register at all. This patch removes the broken LSR checks. Cc: Ming Lei Reported-by: Mike Williams Signed-off-by: Will Deacon --- arch/arm/include/asm/cti.h | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'arch') 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) */ static inline void cti_unlock(struct cti *cti) { - void __iomem *base = cti->base; - unsigned long val; - - val = __raw_readl(base + LOCKSTATUS); - - if (val & 1) { - val = LOCKCODE; - __raw_writel(val, base + LOCKACCESS); - } + __raw_writel(LOCKCODE, cti->base + LOCKACCESS); } /** @@ -166,14 +158,6 @@ static inline void cti_unlock(struct cti *cti) */ static inline void cti_lock(struct cti *cti) { - void __iomem *base = cti->base; - unsigned long val; - - val = __raw_readl(base + LOCKSTATUS); - - if (!(val & 1)) { - val = ~LOCKCODE; - __raw_writel(val, base + LOCKACCESS); - } + __raw_writel(~LOCKCODE, cti->base + LOCKACCESS); } #endif -- cgit v1.2.1