Skip to content

Commit

Permalink
LoongArch: Move three functions from kprobes.c to inst.c
Browse files Browse the repository at this point in the history
The three functions insns_not_supported(), insns_need_simulation() and
arch_simulate_insn() will be used for uprobes, move them from kprobes.c
to inst.c, this is preparation for later patch, no functionality change.

Tested-by: Jeff Xie <xiehuan09@gmail.com>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
  • Loading branch information
seehearfeel authored and chenhuacai committed Jun 29, 2023
1 parent 7b0a096 commit 3d2c3da
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 44 deletions.
4 changes: 4 additions & 0 deletions arch/loongarch/include/asm/inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ static inline bool is_self_loop_ins(union loongarch_instruction *ip, struct pt_r
void simu_pc(struct pt_regs *regs, union loongarch_instruction insn);
void simu_branch(struct pt_regs *regs, union loongarch_instruction insn);

bool insns_not_supported(union loongarch_instruction insn);
bool insns_need_simulation(union loongarch_instruction insn);
void arch_simulate_insn(union loongarch_instruction insn, struct pt_regs *regs);

int larch_insn_read(void *addr, u32 *insnp);
int larch_insn_write(void *addr, u32 insn);
int larch_insn_patch_text(void *addr, u32 insn);
Expand Down
39 changes: 39 additions & 0 deletions arch/loongarch/kernel/inst.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,45 @@ void simu_branch(struct pt_regs *regs, union loongarch_instruction insn)
}
}

bool insns_not_supported(union loongarch_instruction insn)
{
switch (insn.reg2i14_format.opcode) {
case llw_op:
case lld_op:
case scw_op:
case scd_op:
pr_notice("ll and sc instructions are not supported\n");
return true;
}

switch (insn.reg1i21_format.opcode) {
case bceqz_op:
pr_notice("bceqz and bcnez instructions are not supported\n");
return true;
}

return false;
}

bool insns_need_simulation(union loongarch_instruction insn)
{
if (is_pc_ins(&insn))
return true;

if (is_branch_ins(&insn))
return true;

return false;
}

void arch_simulate_insn(union loongarch_instruction insn, struct pt_regs *regs)
{
if (is_pc_ins(&insn))
simu_pc(regs, insn);
else if (is_branch_ins(&insn))
simu_branch(regs, insn);
}

int larch_insn_read(void *addr, u32 *insnp)
{
int ret;
Expand Down
46 changes: 2 additions & 44 deletions arch/loongarch/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,6 @@ static const union loongarch_instruction singlestep_insn = {
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);

static bool insns_not_supported(union loongarch_instruction insn)
{
switch (insn.reg2i14_format.opcode) {
case llw_op:
case lld_op:
case scw_op:
case scd_op:
pr_notice("kprobe: ll and sc instructions are not supported\n");
return true;
}

switch (insn.reg1i21_format.opcode) {
case bceqz_op:
pr_notice("kprobe: bceqz and bcnez instructions are not supported\n");
return true;
}

return false;
}
NOKPROBE_SYMBOL(insns_not_supported);

static bool insns_need_simulation(struct kprobe *p)
{
if (is_pc_ins(&p->opcode))
return true;

if (is_branch_ins(&p->opcode))
return true;

return false;
}
NOKPROBE_SYMBOL(insns_need_simulation);

static void arch_simulate_insn(struct kprobe *p, struct pt_regs *regs)
{
if (is_pc_ins(&p->opcode))
simu_pc(regs, p->opcode);
else if (is_branch_ins(&p->opcode))
simu_branch(regs, p->opcode);
}
NOKPROBE_SYMBOL(arch_simulate_insn);

static void arch_prepare_ss_slot(struct kprobe *p)
{
p->ainsn.insn[0] = *p->addr;
Expand All @@ -89,7 +47,7 @@ int arch_prepare_kprobe(struct kprobe *p)
if (insns_not_supported(p->opcode))
return -EINVAL;

if (insns_need_simulation(p)) {
if (insns_need_simulation(p->opcode)) {
p->ainsn.insn = NULL;
} else {
p->ainsn.insn = get_insn_slot();
Expand Down Expand Up @@ -220,7 +178,7 @@ static void setup_singlestep(struct kprobe *p, struct pt_regs *regs,
regs->csr_era = (unsigned long)p->ainsn.insn;
} else {
/* simulate single steping */
arch_simulate_insn(p, regs);
arch_simulate_insn(p->opcode, regs);
/* now go for post processing */
post_kprobe_handler(p, kcb, regs);
}
Expand Down

0 comments on commit 3d2c3da

Please sign in to comment.