aboutsummaryrefslogtreecommitdiff
path: root/arch/loongarch
diff options
context:
space:
mode:
authorGravatar Tiezhu Yang <yangtiezhu@loongson.cn> 2023-06-29 20:58:44 +0800
committerGravatar Huacai Chen <chenhuacai@loongson.cn> 2023-06-29 20:58:44 +0800
commit49ed320da5f52ec729e7f2f9edbc6e79848455bd (patch)
tree1de5fb0ee897b261b3408e0d1cb45103998bcbd6 /arch/loongarch
parentLoongArch: Check for AMO instructions in insns_not_supported() (diff)
downloadlinux-49ed320da5f52ec729e7f2f9edbc6e79848455bd.tar.gz
linux-49ed320da5f52ec729e7f2f9edbc6e79848455bd.tar.bz2
linux-49ed320da5f52ec729e7f2f9edbc6e79848455bd.zip
LoongArch: Add larch_insn_gen_break() to generate break insns
There exist various break insns such as BRK_KPROBE_BP, BRK_KPROBE_SSTEPBP, BRK_UPROBE_BP and BRK_UPROBE_XOLBP, add larch_insn_gen_break() to generate break insns simpler, this is preparation for later patch. Tested-by: Jeff Xie <xiehuan09@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch/loongarch')
-rw-r--r--arch/loongarch/include/asm/inst.h12
-rw-r--r--arch/loongarch/kernel/inst.c14
2 files changed, 26 insertions, 0 deletions
diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
index a8b88a09a1b0..71e1ed4165c8 100644
--- a/arch/loongarch/include/asm/inst.h
+++ b/arch/loongarch/include/asm/inst.h
@@ -482,6 +482,8 @@ u32 larch_insn_gen_nop(void);
u32 larch_insn_gen_b(unsigned long pc, unsigned long dest);
u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest);
+u32 larch_insn_gen_break(int imm);
+
u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongarch_gpr rk);
u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj);
@@ -500,6 +502,16 @@ static inline bool unsigned_imm_check(unsigned long val, unsigned int bit)
return val < (1UL << bit);
}
+#define DEF_EMIT_REG0I15_FORMAT(NAME, OP) \
+static inline void emit_##NAME(union loongarch_instruction *insn, \
+ int imm) \
+{ \
+ insn->reg0i15_format.opcode = OP; \
+ insn->reg0i15_format.immediate = imm; \
+}
+
+DEF_EMIT_REG0I15_FORMAT(break, break_op)
+
#define DEF_EMIT_REG0I26_FORMAT(NAME, OP) \
static inline void emit_##NAME(union loongarch_instruction *insn, \
int offset) \
diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c
index a3169cf1cc31..3050329556d1 100644
--- a/arch/loongarch/kernel/inst.c
+++ b/arch/loongarch/kernel/inst.c
@@ -253,6 +253,20 @@ u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest)
return insn.word;
}
+u32 larch_insn_gen_break(int imm)
+{
+ union loongarch_instruction insn;
+
+ if (imm < 0 || imm >= SZ_32K) {
+ pr_warn("The generated break instruction is out of range.\n");
+ return INSN_BREAK;
+ }
+
+ emit_break(&insn, imm);
+
+ return insn.word;
+}
+
u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongarch_gpr rk)
{
union loongarch_instruction insn;