arm64: kgdb: handle read-only text / modules
Subsystems (2)
PATCH v2 1/1 arm64: kgdb: handle read-only text / modules
Handle read-only cases (CONFIG_DEBUG_RODATA/CONFIG_DEBUG_SET_MODULE_RONX) by using aarch64_insn_write() instead of probe_kernel_write(). See how this works:
commit 2f896d586610 ("arm64: use fixmap for text patching")--- arch/arm64/include/asm/debug-monitors.h | 2 -- arch/arm64/kernel/kgdb.c | 36 ++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 14 deletions(-)
arch/arm64/include/asm/debug-monitors.h +0 -2
@@ -61,8 +61,6 @@#define AARCH64_BREAK_KGDB_DYN_DBG \ (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) -#define KGDB_DYN_BRK_INS_BYTE (x) \ - ((AARCH64_BREAK_KGDB_DYN_DBG >> (8 * (x))) & 0xff)#define CACHE_FLUSH_IS_SAFE 1
arch/arm64/kernel/kgdb.c +24 -12
@@ -19,6 +19,7 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/bug.h> #include <linux/cpumask.h> #include <linux/irq.h> #include <linux/irq_work.h>
@@ -26,6 +27,8 @@#include <linux/kgdb.h> #include <linux/kprobes.h> #include <linux/percpu.h> +#include <asm/debug-monitors.h> +#include <asm/insn.h> #include <asm/ptrace.h> #include <asm/traps.h>
@@ -370,15 +373,24 @@ void kgdb_arch_exit(void)unregister_die_notifier (&kgdb_notifier); } -/* -* ARM instructions are always in LE. -* Break instruction is encoded in LE format -*/ -struct kgdb_arch arch_kgdb_ops = { - .gdb_bpt_instr = { -KGDB_DYN_BRK_INS_BYTE (0 ), -KGDB_DYN_BRK_INS_BYTE (1 ), -KGDB_DYN_BRK_INS_BYTE (2 ), -KGDB_DYN_BRK_INS_BYTE (3 ), - } -}; +struct kgdb_arch arch_kgdb_ops; + +int kgdb_arch_set_breakpoint (struct kgdb_bkpt *bpt) +{ +int err; + +BUILD_BUG_ON (AARCH64_INSN_SIZE !=BREAK_INSTR_SIZE ); + + err =aarch64_insn_read ((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr); +if (err) +return err; + +return aarch64_insn_write ((void *)bpt->bpt_addr, + (u32 )AARCH64_BREAK_KGDB_DYN_DBG ); +} + +int kgdb_arch_remove_breakpoint (struct kgdb_bkpt *bpt) +{ +return aarch64_insn_write ((void *)bpt->bpt_addr, + *(u32 *)bpt->saved_instr); +}
Signature · 1 line
2.10.0
Mark Rutland
reviewerPATCH v2 1/1 arm64: kgdb: handle read-only text / modules
Quoted 11 lines · AKASHI Takahiro
Handle read-only cases (CONFIG_DEBUG_RODATA/CONFIG_DEBUG_SET_MODULE_RONX) by using
aarch64_insn_write()instead ofprobe_kernel_write(). See how this works:commit 2f896d586610 ("arm64: use fixmap for text patching")Signed-off-by AKASHI Takahiro <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Jason Wessel <[email protected]>Cc <[email protected]> # 3.18-3.19: 2f896d5: arm64: use fixmapCc <[email protected]> # 4.0-
For v3.18-v3.19, we also need commit f6242cac10427c54 ("arm64: Fix text patching logic when using fixmap"), so as to not break the !CONFIG_DEBUG_SET_MODULE_RONX case.
With that:
Thanks,
Mark.
Quoted 79 lines
--- arch/arm64/include/asm/debug-monitors.h | 2 -- arch/arm64/kernel/kgdb.c | 36 ++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 14 deletions(-)arch/arm64/include/asm/debug-monitors.h +0
-2@@ -61,8 +61,6 @@#define AARCH64_BREAK_KGDB_DYN_DBG \ (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) -#define KGDB_DYN_BRK_INS_BYTE (x) \ - ((AARCH64_BREAK_KGDB_DYN_DBG >> (8 * (x))) & 0xff)#define CACHE_FLUSH_IS_SAFE 1arch/arm64/kernel/kgdb.c +24
-12@@ -19,6 +19,7 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/bug.h> #include <linux/cpumask.h> #include <linux/irq.h> #include <linux/irq_work.h> @@ -26,6 +27,8 @@#include <linux/kgdb.h> #include <linux/kprobes.h> #include <linux/percpu.h> +#include <asm/debug-monitors.h> +#include <asm/insn.h> #include <asm/ptrace.h> #include <asm/traps.h> @@ -370,15 +373,24 @@ void kgdb_arch_exit(void)unregister_die_notifier (&kgdb_notifier); } -/* -* ARM instructions are always in LE. -* Break instruction is encoded in LE format -*/ -struct kgdb_arch arch_kgdb_ops = { - .gdb_bpt_instr = { -KGDB_DYN_BRK_INS_BYTE (0 ), -KGDB_DYN_BRK_INS_BYTE (1 ), -KGDB_DYN_BRK_INS_BYTE (2 ), -KGDB_DYN_BRK_INS_BYTE (3 ), - } -}; +struct kgdb_arch arch_kgdb_ops; + +int kgdb_arch_set_breakpoint (struct kgdb_bkpt *bpt) +{ +int err; + +BUILD_BUG_ON (AARCH64_INSN_SIZE !=BREAK_INSTR_SIZE ); + + err =aarch64_insn_read ((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr); +if (err) +return err; + +return aarch64_insn_write ((void *)bpt->bpt_addr, + (u32 )AARCH64_BREAK_KGDB_DYN_DBG ); +} + +int kgdb_arch_remove_breakpoint (struct kgdb_bkpt *bpt) +{ +return aarch64_insn_write ((void *)bpt->bpt_addr, + *(u32 *)bpt->saved_instr); +}Signature · 1 line
2.10.0
PATCH v2 1/1 arm64: kgdb: handle read-only text / modules
Quoted 13 lines · Mark Rutland
Quoted 11 lines · AKASHI Takahiro
Handle read-only cases (CONFIG_DEBUG_RODATA/CONFIG_DEBUG_SET_MODULE_RONX) by using
aarch64_insn_write()instead ofprobe_kernel_write(). See how this works:commit 2f896d586610 ("arm64: use fixmap for text patching")Signed-off-by AKASHI Takahiro <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Jason Wessel <[email protected]>Cc <[email protected]> # 3.18-3.19: 2f896d5: arm64: use fixmapCc <[email protected]> # 4.0-
Quoted 3 lines
For v3.18-v3.19, we also need commit
f6242cac10427c54("arm64: Fix text patching logic when using fixmap"), so as to not break the !CONFIG_DEBUG_SET_MODULE_RONX case.
Ah, thank you.
I will post the patch as v2.1.
-Takahiro AKASHI
Quoted 86 lines
With that:
Reviewed-by Mark Rutland <[email protected]>Thanks,
Mark.Quoted 79 lines
--- arch/arm64/include/asm/debug-monitors.h | 2 -- arch/arm64/kernel/kgdb.c | 36 ++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 14 deletions(-)arch/arm64/include/asm/debug-monitors.h +0
-2@@ -61,8 +61,6 @@#define AARCH64_BREAK_KGDB_DYN_DBG \ (AARCH64_BREAK_MON | (KGDB_DYN_DBG_BRK_IMM << 5)) -#define KGDB_DYN_BRK_INS_BYTE (x) \ - ((AARCH64_BREAK_KGDB_DYN_DBG >> (8 * (x))) & 0xff)#define CACHE_FLUSH_IS_SAFE 1arch/arm64/kernel/kgdb.c +24
-12@@ -19,6 +19,7 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/bug.h> #include <linux/cpumask.h> #include <linux/irq.h> #include <linux/irq_work.h> @@ -26,6 +27,8 @@#include <linux/kgdb.h> #include <linux/kprobes.h> #include <linux/percpu.h> +#include <asm/debug-monitors.h> +#include <asm/insn.h> #include <asm/ptrace.h> #include <asm/traps.h> @@ -370,15 +373,24 @@ void kgdb_arch_exit(void)unregister_die_notifier (&kgdb_notifier); } -/* -* ARM instructions are always in LE. -* Break instruction is encoded in LE format -*/ -struct kgdb_arch arch_kgdb_ops = { - .gdb_bpt_instr = { -KGDB_DYN_BRK_INS_BYTE (0 ), -KGDB_DYN_BRK_INS_BYTE (1 ), -KGDB_DYN_BRK_INS_BYTE (2 ), -KGDB_DYN_BRK_INS_BYTE (3 ), - } -}; +struct kgdb_arch arch_kgdb_ops; + +int kgdb_arch_set_breakpoint (struct kgdb_bkpt *bpt) +{ +int err; + +BUILD_BUG_ON (AARCH64_INSN_SIZE !=BREAK_INSTR_SIZE ); + + err =aarch64_insn_read ((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr); +if (err) +return err; + +return aarch64_insn_write ((void *)bpt->bpt_addr, + (u32 )AARCH64_BREAK_KGDB_DYN_DBG ); +} + +int kgdb_arch_remove_breakpoint (struct kgdb_bkpt *bpt) +{ +return aarch64_insn_write ((void *)bpt->bpt_addr, + *(u32 *)bpt->saved_instr); +}Signature · 1 line
2.10.0