aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAKASHI Takahiro <takahiro.akashi@linaro.org>2016-09-23 03:42:08 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2016-09-23 06:25:01 -0400
commit67787b68ec48c239d5ec12f9bf5adaf5c459517a (patch)
tree807c1243a2458bb8a83d527c4970ad48840f87ee
parentc18df0adabf8400c1825b90382d06df5edc303fa (diff)
arm64: kgdb: handle read-only text / modules
Handle read-only cases when CONFIG_DEBUG_RODATA (4.0) or CONFIG_DEBUG_SET_MODULE_RONX (3.18) are enabled by using aarch64_insn_write() instead of probe_kernel_write() as introduced by commit 2f896d586610 ("arm64: use fixmap for text patching") in 4.0. Fixes: 11d91a770f1f ("arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support") Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Reviewed-by: Mark Rutland <mark.rutland@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/include/asm/debug-monitors.h2
-rw-r--r--arch/arm64/kernel/kgdb.c36
2 files changed, 24 insertions, 14 deletions
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 4b6b3f72a215..b71420a12f26 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -61,8 +61,6 @@
61 61
62#define AARCH64_BREAK_KGDB_DYN_DBG \ 62#define AARCH64_BREAK_KGDB_DYN_DBG \
63 (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) 63 (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5))
64#define KGDB_DYN_BRK_INS_BYTE(x) \
65 ((AARCH64_BREAK_KGDB_DYN_DBG >> (8 * (x))) & 0xff)
66 64
67#define CACHE_FLUSH_IS_SAFE 1 65#define CACHE_FLUSH_IS_SAFE 1
68 66
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index 8c57f6496e56..e017a9493b92 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -19,10 +19,13 @@
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */ 20 */
21 21
22#include <linux/bug.h>
22#include <linux/irq.h> 23#include <linux/irq.h>
23#include <linux/kdebug.h> 24#include <linux/kdebug.h>
24#include <linux/kgdb.h> 25#include <linux/kgdb.h>
25#include <linux/kprobes.h> 26#include <linux/kprobes.h>
27#include <asm/debug-monitors.h>
28#include <asm/insn.h>
26#include <asm/traps.h> 29#include <asm/traps.h>
27 30
28struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { 31struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
@@ -338,15 +341,24 @@ void kgdb_arch_exit(void)
338 unregister_die_notifier(&kgdb_notifier); 341 unregister_die_notifier(&kgdb_notifier);
339} 342}
340 343
341/* 344struct kgdb_arch arch_kgdb_ops;
342 * ARM instructions are always in LE. 345
343 * Break instruction is encoded in LE format 346int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
344 */ 347{
345struct kgdb_arch arch_kgdb_ops = { 348 int err;
346 .gdb_bpt_instr = { 349
347 KGDB_DYN_BRK_INS_BYTE(0), 350 BUILD_BUG_ON(AARCH64_INSN_SIZE != BREAK_INSTR_SIZE);
348 KGDB_DYN_BRK_INS_BYTE(1), 351
349 KGDB_DYN_BRK_INS_BYTE(2), 352 err = aarch64_insn_read((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr);
350 KGDB_DYN_BRK_INS_BYTE(3), 353 if (err)
351 } 354 return err;
352}; 355
356 return aarch64_insn_write((void *)bpt->bpt_addr,
357 (u32)AARCH64_BREAK_KGDB_DYN_DBG);
358}
359
360int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
361{
362 return aarch64_insn_write((void *)bpt->bpt_addr,
363 *(u32 *)bpt->saved_instr);
364}