LoongArch: Move three functions from kprobes.c to inst.c
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>
This commit is contained in:
parent
7b0a096436
commit
3d2c3daf82
|
@ -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_pc(struct pt_regs *regs, union loongarch_instruction insn);
|
||||||
void simu_branch(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_read(void *addr, u32 *insnp);
|
||||||
int larch_insn_write(void *addr, u32 insn);
|
int larch_insn_write(void *addr, u32 insn);
|
||||||
int larch_insn_patch_text(void *addr, u32 insn);
|
int larch_insn_patch_text(void *addr, u32 insn);
|
||||||
|
|
|
@ -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 larch_insn_read(void *addr, u32 *insnp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -21,48 +21,6 @@ static const union loongarch_instruction singlestep_insn = {
|
||||||
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
|
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
|
||||||
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
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)
|
static void arch_prepare_ss_slot(struct kprobe *p)
|
||||||
{
|
{
|
||||||
p->ainsn.insn[0] = *p->addr;
|
p->ainsn.insn[0] = *p->addr;
|
||||||
|
@ -89,7 +47,7 @@ int arch_prepare_kprobe(struct kprobe *p)
|
||||||
if (insns_not_supported(p->opcode))
|
if (insns_not_supported(p->opcode))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (insns_need_simulation(p)) {
|
if (insns_need_simulation(p->opcode)) {
|
||||||
p->ainsn.insn = NULL;
|
p->ainsn.insn = NULL;
|
||||||
} else {
|
} else {
|
||||||
p->ainsn.insn = get_insn_slot();
|
p->ainsn.insn = get_insn_slot();
|
||||||
|
@ -220,7 +178,7 @@ static void setup_singlestep(struct kprobe *p, struct pt_regs *regs,
|
||||||
regs->csr_era = (unsigned long)p->ainsn.insn;
|
regs->csr_era = (unsigned long)p->ainsn.insn;
|
||||||
} else {
|
} else {
|
||||||
/* simulate single steping */
|
/* simulate single steping */
|
||||||
arch_simulate_insn(p, regs);
|
arch_simulate_insn(p->opcode, regs);
|
||||||
/* now go for post processing */
|
/* now go for post processing */
|
||||||
post_kprobe_handler(p, kcb, regs);
|
post_kprobe_handler(p, kcb, regs);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue