All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: Jordan Niethe <jniethe5@gmail.com>
Cc: Alistair Popple <alistair@popple.id.au>,
	Daniel Axtens <dja@axtens.net>,
	linuxppc-dev@lists.ozlabs.org,
	Balamuruhan S <bala24@linux.ibm.com>
Subject: Re: [PATCH v3 11/14] powerpc/kprobes: Support kprobes on prefixed instructions
Date: Fri, 28 Feb 2020 11:47:48 +1000	[thread overview]
Message-ID: <1582853017.uien0qdstw.astroid@bobo.none> (raw)
In-Reply-To: <CACzsE9r+dKAgmTPsWtzPTnjmVskG_BO5G3=0V_Qm_6pu-_ZRFg@mail.gmail.com>

Jordan Niethe's on February 27, 2020 10:58 am:
> On Wed, Feb 26, 2020 at 6:18 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Jordan Niethe's on February 26, 2020 2:07 pm:
>> > @@ -136,11 +148,14 @@ int arch_prepare_kprobe(struct kprobe *p)
>> >       }
>> >
>> >       if (!ret) {
>> > -             patch_instruction(p->ainsn.insn, *p->addr);
>> > +             patch_instruction(&p->ainsn.insn[0], p->addr[0]);
>> > +             if (IS_PREFIX(insn))
>> > +                     patch_instruction(&p->ainsn.insn[1], p->addr[1]);
>> >               p->opcode = *p->addr;
>>
>> Not to single out this hunk or this patch even, but what do you reckon
>> about adding an instruction data type, and then use that in all these
>> call sites rather than adding the extra arg or doing the extra copy
>> manually in each place depending on prefix?
>>
>> instrs_are_equal, get_user_instr, analyse_instr, patch_instruction,
>> etc., would all take this new instr. Places that open code a memory
>> access like your MCE change need some accessor
>>
>>                instr = *(unsigned int *)(instr_addr);
>> -               if (!analyse_instr(&op, &tmp, instr, PPC_NO_SUFFIX)) {
>> +               if (IS_PREFIX(instr))
>> +                       suffix = *(unsigned int *)(instr_addr + 4);
>>
>> Becomes
>>                read_instr(instr_addr, &instr);
>>                if (!analyse_instr(&op, &tmp, instr)) ...
>>
>> etc.
> Daniel Axtens also talked about this and my reasons not to do so were
> pretty unconvincing, so I started trying something like this. One

Okay.

> thing I have been wondering is how pervasive should the new type be.

I wouldn't mind it being quite pervasive. We have to be careful not
to copy it directly to/from memory now, but if we have accessors to
do all that with, I think it should be okay.

> Below is data type I have started using, which I think works
> reasonably for replacing unsigned ints everywhere (like within
> code-patching.c). In a few architecture independent places such as
> uprobes which want to do ==, etc the union type does not work so well.

There will be some places you have to make the boundary. I would start
by just making it a powerpc thing, but possibly there is or could be
some generic helpers. How does something like x86 cope with this?

> I will have the next revision of the series start using a type.

Thanks for doing that.

> 
> diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> new file mode 100644
> index 000000000000..50adb3dbdeb4
> --- /dev/null
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -0,0 +1,87 @@
> +
> +#ifndef _ASM_INST_H
> +#define _ASM_INST_H
> +
> +#ifdef __powerpc64__
> +
> +/* 64  bit Instruction */
> +
> +typedef struct {
> +    unsigned int prefix;
> +    unsigned int suffix;

u32?

> +} __packed ppc_prefixed_inst;
> +
> +typedef union ppc_inst {
> +    unsigned int w;
> +    ppc_prefixed_inst p;
> +} ppc_inst;

I'd make it a struct and use nameless structs/unions inside it (with
appropriate packed annotation):

struct ppc_inst {
    union {
        struct {
            u32 word;
	    u32 pad;
	};
	struct {
	    u32 prefix;
	    u32 suffix;
	};
    };
};

> +
> +#define PPC_INST_IS_PREFIXED(inst) (((inst).w >> 26) == 1)
> +#define PPC_INST_LEN(inst) (PPC_INST_IS_PREFIXED((inst)) ?
> sizeof((inst).p) : sizeof((inst).w))

Good accessors, I'd make them all C inline functions and lower case.

> +
> +#define PPC_INST_NEW_WORD(x) ((ppc_inst) { .w = (x) })
> +#define PPC_INST_NEW_WORD_PAD(x) ((ppc_inst) { .p.prefix = (x),
> .p.suffix = (0x60000000) })
> +#define PPC_INST_NEW_PREFIXED(x, y) ((ppc_inst) { .p.prefix = (x),
> .p.suffix = (y) })

If these are widely used, I'd make them a bit shorter

#define PPC_INST(x)
#define PPC_INST_PREFIXED(x)

I'd also set padding to something invalid 0 or 0xffffffff for the first
case, and have your accessors check that rather than carrying around
another type of ppc_inst (prefixed, padded, non-padded).

> +
> +#define PPC_INST_WORD(x) ((x).w)
> +#define PPC_INST_PREFIX(x) (x.p.prefix)
> +#define PPC_INST_SUFFIX(x) (x.p.suffix)
> +#define PPC_INST_EMPTY(x) (PPC_INST_WORD(x) == 0)

I'd avoid simple accessors like this completely. If they have any use
it would be to ensure you don't try to use prefix/suffix on a 
non-prefixed instruction for example. If you want to do that I'd use
inline functions for it.

> +
> +#define DEREF_PPC_INST_PTR(ptr)                \
> +({                            \
> +    ppc_inst __inst;                \
> +    __inst.w = *(unsigned int *)(ptr);        \
> +    if (PPC_INST_IS_PREFIXED(__inst))        \
> +        __inst.p = *(ppc_prefixed_inst *)(ptr);    \
> +    __inst;                        \
> +})

I'd go an inline with shorter lowercase names. ppc_inst_read(&inst);

> +#define PPC_INST_NEXT(ptr) ((ptr) += PPC_INST_LEN(DEREF_PPC_INST_PTR((ptr))))
> +#define PPC_INST_PREV(ptr) ((ptr) -= PPC_INST_LEN(DEREF_PPC_INST_PTR((ptr))))

Wouldn't bother with this accessor, caller could ptr += ppc_inst_len(inst)


> +#define PPC_INST_EQ(x, y)                \
> +({                            \
> +    long pic_ret = 0;                \
> +    pic_ret = (PPC_INST_PREFIX(x) == PPC_INST_PREFIX(y));    \
> +    if (pic_ret) {                    \
> +        if (PPC_INST_IS_PREFIXED(x) && PPC_INST_IS_PREFIXED(y)) {    \
> +            pic_ret = (PPC_INST_SUFFIX(x) == PPC_INST_SUFFIX(y));    \
> +        } else {                \
> +            pic_ret = 0;            \
> +        }                    \
> +    }                        \
> +    pic_ret;                    \
> +})

static inline bool ppc_inst_eq(struct ppc_inst x, struct ppc_inst y)
{
	return !memcmp(&x, &y, sizeof(struct ppc_inst));
}

If all accessors and initalisers are such that the padding gets set,
that'll work.

Thanks,
Nick

  reply	other threads:[~2020-02-28  1:50 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-26  4:07 [PATCH v3 00/14] Initial Prefixed Instruction support Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 01/14] powerpc: Enable Prefixed Instructions Jordan Niethe
2020-02-26  6:46   ` Nicholas Piggin
2020-02-28  2:52     ` Jordan Niethe
2020-02-28  4:48       ` Nicholas Piggin
2020-03-03 23:20         ` Alistair Popple
2020-02-26  4:07 ` [PATCH v3 02/14] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
2020-03-03 23:31   ` Alistair Popple
2020-02-26  4:07 ` [PATCH v3 03/14] powerpc sstep: Prepare to support prefixed instructions Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 04/14] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 05/14] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 06/14] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 07/14] powerpc/traps: Check for prefixed instructions in facility_unavailable_exception() Jordan Niethe
2020-02-26  6:49   ` Nicholas Piggin
2020-02-26 23:52     ` Jordan Niethe
2020-02-28  1:57       ` Nicholas Piggin
2020-02-26  4:07 ` [PATCH v3 08/14] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
2020-02-26  7:00   ` Nicholas Piggin
2020-02-26 23:54     ` Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 09/14] powerpc/xmon: Add initial support for prefixed instructions Jordan Niethe
2020-02-26  7:06   ` Nicholas Piggin
2020-02-27  0:11     ` Jordan Niethe
2020-02-27  7:14       ` Christophe Leroy
2020-02-28  0:37         ` Jordan Niethe
2020-02-28  1:23           ` Nicholas Piggin
2020-02-26  4:07 ` [PATCH v3 10/14] powerpc/xmon: Dump " Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 11/14] powerpc/kprobes: Support kprobes on " Jordan Niethe
2020-02-26  7:14   ` Nicholas Piggin
2020-02-27  0:58     ` Jordan Niethe
2020-02-28  1:47       ` Nicholas Piggin [this message]
2020-02-28  1:56         ` Nicholas Piggin
2020-02-28  3:23         ` Jordan Niethe
2020-02-28  4:53           ` Nicholas Piggin
2020-02-26  4:07 ` [PATCH v3 12/14] powerpc/uprobes: Add support for " Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 13/14] powerpc/hw_breakpoints: Initial " Jordan Niethe
2020-02-26  4:07 ` [PATCH v3 14/14] powerpc: Add prefix support to mce_find_instr_ea_and_pfn() Jordan Niethe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1582853017.uien0qdstw.astroid@bobo.none \
    --to=npiggin@gmail.com \
    --cc=alistair@popple.id.au \
    --cc=bala24@linux.ibm.com \
    --cc=dja@axtens.net \
    --cc=jniethe5@gmail.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.