[PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length

Jordan Niethe jniethe5 at gmail.com
Wed Apr 8 12:14:04 AEST 2020


On Tue, Apr 7, 2020 at 9:15 PM Balamuruhan S <bala24 at linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > Currently all instructions have the same length, but in preparation for
> > prefixed instructions introduce a function for returning instruction
> > length.
> >
> > Signed-off-by: Jordan Niethe <jniethe5 at gmail.com>
> > ---
> >  arch/powerpc/include/asm/inst.h | 5 +++++
> >  arch/powerpc/kernel/kprobes.c   | 6 ++++--
> >  arch/powerpc/kernel/uprobes.c   | 2 +-
> >  3 files changed, 10 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/inst.h
> > b/arch/powerpc/include/asm/inst.h
> > index 369b35ce964c..70b37a35a91a 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -17,6 +17,11 @@ static inline u32 ppc_inst_val(struct ppc_inst x)
> >       return x.val;
> >  }
> >
> > +static inline bool ppc_inst_len(struct ppc_inst x)
>
>
> return type shouldn't be a bool, `size_t` instead.
Thank you.
>
> -- Bala
>
> > +{
> > +     return sizeof(struct ppc_inst);
> > +}
> > +
> >  static inline int ppc_inst_opcode(struct ppc_inst x)
> >  {
> >       return x.val >> 26;
> > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> > index ff53e5ef7e40..8d17cfdcdc54 100644
> > --- a/arch/powerpc/kernel/kprobes.c
> > +++ b/arch/powerpc/kernel/kprobes.c
> > @@ -474,14 +474,16 @@ NOKPROBE_SYMBOL(trampoline_probe_handler);
> >   */
> >  int kprobe_post_handler(struct pt_regs *regs)
> >  {
> > +     int len;
> >       struct kprobe *cur = kprobe_running();
> >       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> >
> >       if (!cur || user_mode(regs))
> >               return 0;
> >
> > +     len = ppc_inst_len(ppc_inst_read((struct ppc_inst *)cur->ainsn.insn));
> >       /* make sure we got here for instruction we have a kprobe on */
> > -     if (((unsigned long)cur->ainsn.insn + 4) != regs->nip)
> > +     if (((unsigned long)cur->ainsn.insn + len) != regs->nip)
> >               return 0;
> >
> >       if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
> > @@ -490,7 +492,7 @@ int kprobe_post_handler(struct pt_regs *regs)
> >       }
> >
> >       /* Adjust nip to after the single-stepped instruction */
> > -     regs->nip = (unsigned long)cur->addr + 4;
> > +     regs->nip = (unsigned long)cur->addr + len;
> >       regs->msr |= kcb->kprobe_saved_msr;
> >
> >       /*Restore back the original saved kprobes variables and continue. */
> > diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> > index 31c870287f2b..8e63afa012ba 100644
> > --- a/arch/powerpc/kernel/uprobes.c
> > +++ b/arch/powerpc/kernel/uprobes.c
> > @@ -112,7 +112,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe,
> > struct pt_regs *regs)
> >        * support doesn't exist and have to fix-up the next instruction
> >        * to be executed.
> >        */
> > -     regs->nip = utask->vaddr + MAX_UINSN_BYTES;
> > +     regs->nip = utask->vaddr + ppc_inst_len(auprobe->insn);
> >
> >       user_disable_single_step(current);
> >       return 0;
>


More information about the Linuxppc-dev mailing list