Re: [PATCH v2 03/13] powerpc sstep: Prepare to support prefixed instructions

2020-02-11 Thread Jordan Niethe
On Tue, Feb 11, 2020 at 4:57 PM Christophe Leroy
 wrote:
>
>
>
> Le 11/02/2020 à 06:33, Jordan Niethe a écrit :
> > Currently all instructions are a single word long. A future ISA version
> > will include prefixed instructions which have a double word length. The
> > functions used for analysing and emulating instructions need to be
> > modified so that they can handle these new instruction types.
> >
> > A prefixed instruction is a word prefix followed by a word suffix. All
> > prefixes uniquely have the primary op-code 1. Suffixes may be valid word
> > instructions or instructions that only exist as suffixes.
> >
> > In handling prefixed instructions it will be convenient to treat the
> > suffix and prefix as separate words. To facilitate this modify
> > analyse_instr() and emulate_step() to take a suffix as a
> > parameter. For word instructions it does not matter what is passed in
> > here - it will be ignored.
> >
> > We also define a new flag, PREFIXED, to be used in instruction_op:type.
> > This flag will indicate when emulating an analysed instruction if the
> > NIP should be advanced by word length or double word length.
> >
> > The callers of analyse_instr() and emulate_step() will need their own
> > changes to be able to support prefixed instructions. For now modify them
> > to pass in 0 as a suffix.
> >
> > Note that at this point no prefixed instructions are emulated or
> > analysed - this is just making it possible to do so.
> >
> > Signed-off-by: Jordan Niethe 
> > ---
> > v2: - Move definition of __get_user_instr() and
> > __get_user_instr_inatomic() to "powerpc: Support prefixed instructions
> > in alignment handler."
> >  - Use a macro for returning the length of an op
> >  - Rename sufx -> suffix
> >  - Define and use PPC_NO_SUFFIX instead of 0
> > ---
> >   arch/powerpc/include/asm/ppc-opcode.h |  5 +
> >   arch/powerpc/include/asm/sstep.h  |  9 ++--
> >   arch/powerpc/kernel/align.c   |  2 +-
> >   arch/powerpc/kernel/hw_breakpoint.c   |  4 ++--
> >   arch/powerpc/kernel/kprobes.c |  2 +-
> >   arch/powerpc/kernel/mce_power.c   |  2 +-
> >   arch/powerpc/kernel/optprobes.c   |  3 ++-
> >   arch/powerpc/kernel/uprobes.c |  2 +-
> >   arch/powerpc/kvm/emulate_loadstore.c  |  2 +-
> >   arch/powerpc/lib/sstep.c  | 12 ++-
> >   arch/powerpc/lib/test_emulate_step.c  | 30 +--
> >   arch/powerpc/xmon/xmon.c  |  5 +++--
> >   12 files changed, 46 insertions(+), 32 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
> > b/arch/powerpc/include/asm/ppc-opcode.h
> > index c1df75edde44..72783bc92e50 100644
> > --- a/arch/powerpc/include/asm/ppc-opcode.h
> > +++ b/arch/powerpc/include/asm/ppc-opcode.h
> > @@ -377,6 +377,11 @@
> >   #define PPC_INST_VCMPEQUD   0x10c7
> >   #define PPC_INST_VCMPEQUB   0x1006
> >
> > +/* macro to check if a word is a prefix */
> > +#define IS_PREFIX(x) (((x) >> 26) == 1)
>
> Can you add an OP_PREFIX in the OP list and use it instead of '1' ?
Will do.
>
> > +#define  PPC_NO_SUFFIX   0
> > +#define  PPC_INST_LENGTH(x)  (IS_PREFIX(x) ? 8 : 4)
> > +
> >   /* macros to insert fields into opcodes */
> >   #define ___PPC_RA(a)(((a) & 0x1f) << 16)
> >   #define ___PPC_RB(b)(((b) & 0x1f) << 11)
> > diff --git a/arch/powerpc/include/asm/sstep.h 
> > b/arch/powerpc/include/asm/sstep.h
> > index 769f055509c9..9ea8904a1549 100644
> > --- a/arch/powerpc/include/asm/sstep.h
> > +++ b/arch/powerpc/include/asm/sstep.h
> > @@ -89,11 +89,15 @@ enum instruction_type {
> >   #define VSX_LDLEFT  4   /* load VSX register from left */
> >   #define VSX_CHECK_VEC   8   /* check MSR_VEC not MSR_VSX for reg 
> > >= 32 */
> >
> > +/* Prefixed flag, ORed in with type */
> > +#define PREFIXED 0x800
> > +
> >   /* Size field in type word */
> >   #define SIZE(n) ((n) << 12)
> >   #define GETSIZE(w)  ((w) >> 12)
> >
> >   #define GETTYPE(t)  ((t) & INSTR_TYPE_MASK)
> > +#define OP_LENGTH(t) (((t) & PREFIXED) ? 8 : 4)
>
> Is it worth naming it OP_LENGTH ? Can't it be mistaken as one of the
> OP_xxx from the list in asm/opcode.h ?
>
> What about GETLENGTH() instead to be consistant with the above lines ?
Good point, will do.
>
> Christophe


Re: [PATCH v2 03/13] powerpc sstep: Prepare to support prefixed instructions

2020-02-10 Thread Christophe Leroy




Le 11/02/2020 à 06:33, Jordan Niethe a écrit :

Currently all instructions are a single word long. A future ISA version
will include prefixed instructions which have a double word length. The
functions used for analysing and emulating instructions need to be
modified so that they can handle these new instruction types.

A prefixed instruction is a word prefix followed by a word suffix. All
prefixes uniquely have the primary op-code 1. Suffixes may be valid word
instructions or instructions that only exist as suffixes.

In handling prefixed instructions it will be convenient to treat the
suffix and prefix as separate words. To facilitate this modify
analyse_instr() and emulate_step() to take a suffix as a
parameter. For word instructions it does not matter what is passed in
here - it will be ignored.

We also define a new flag, PREFIXED, to be used in instruction_op:type.
This flag will indicate when emulating an analysed instruction if the
NIP should be advanced by word length or double word length.

The callers of analyse_instr() and emulate_step() will need their own
changes to be able to support prefixed instructions. For now modify them
to pass in 0 as a suffix.

Note that at this point no prefixed instructions are emulated or
analysed - this is just making it possible to do so.

Signed-off-by: Jordan Niethe 
---
v2: - Move definition of __get_user_instr() and
__get_user_instr_inatomic() to "powerpc: Support prefixed instructions
in alignment handler."
 - Use a macro for returning the length of an op
 - Rename sufx -> suffix
 - Define and use PPC_NO_SUFFIX instead of 0
---
  arch/powerpc/include/asm/ppc-opcode.h |  5 +
  arch/powerpc/include/asm/sstep.h  |  9 ++--
  arch/powerpc/kernel/align.c   |  2 +-
  arch/powerpc/kernel/hw_breakpoint.c   |  4 ++--
  arch/powerpc/kernel/kprobes.c |  2 +-
  arch/powerpc/kernel/mce_power.c   |  2 +-
  arch/powerpc/kernel/optprobes.c   |  3 ++-
  arch/powerpc/kernel/uprobes.c |  2 +-
  arch/powerpc/kvm/emulate_loadstore.c  |  2 +-
  arch/powerpc/lib/sstep.c  | 12 ++-
  arch/powerpc/lib/test_emulate_step.c  | 30 +--
  arch/powerpc/xmon/xmon.c  |  5 +++--
  12 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index c1df75edde44..72783bc92e50 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -377,6 +377,11 @@
  #define PPC_INST_VCMPEQUD 0x10c7
  #define PPC_INST_VCMPEQUB 0x1006
  
+/* macro to check if a word is a prefix */

+#define IS_PREFIX(x)   (((x) >> 26) == 1)


Can you add an OP_PREFIX in the OP list and use it instead of '1' ?


+#definePPC_NO_SUFFIX   0
+#definePPC_INST_LENGTH(x)  (IS_PREFIX(x) ? 8 : 4)
+
  /* macros to insert fields into opcodes */
  #define ___PPC_RA(a)  (((a) & 0x1f) << 16)
  #define ___PPC_RB(b)  (((b) & 0x1f) << 11)
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 769f055509c9..9ea8904a1549 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -89,11 +89,15 @@ enum instruction_type {
  #define VSX_LDLEFT4   /* load VSX register from left */
  #define VSX_CHECK_VEC 8   /* check MSR_VEC not MSR_VSX for reg >= 32 */
  
+/* Prefixed flag, ORed in with type */

+#define PREFIXED   0x800
+
  /* Size field in type word */
  #define SIZE(n)   ((n) << 12)
  #define GETSIZE(w)((w) >> 12)
  
  #define GETTYPE(t)	((t) & INSTR_TYPE_MASK)

+#define OP_LENGTH(t)   (((t) & PREFIXED) ? 8 : 4)


Is it worth naming it OP_LENGTH ? Can't it be mistaken as one of the 
OP_xxx from the list in asm/opcode.h ?


What about GETLENGTH() instead to be consistant with the above lines ?

Christophe


[PATCH v2 03/13] powerpc sstep: Prepare to support prefixed instructions

2020-02-10 Thread Jordan Niethe
Currently all instructions are a single word long. A future ISA version
will include prefixed instructions which have a double word length. The
functions used for analysing and emulating instructions need to be
modified so that they can handle these new instruction types.

A prefixed instruction is a word prefix followed by a word suffix. All
prefixes uniquely have the primary op-code 1. Suffixes may be valid word
instructions or instructions that only exist as suffixes.

In handling prefixed instructions it will be convenient to treat the
suffix and prefix as separate words. To facilitate this modify
analyse_instr() and emulate_step() to take a suffix as a
parameter. For word instructions it does not matter what is passed in
here - it will be ignored.

We also define a new flag, PREFIXED, to be used in instruction_op:type.
This flag will indicate when emulating an analysed instruction if the
NIP should be advanced by word length or double word length.

The callers of analyse_instr() and emulate_step() will need their own
changes to be able to support prefixed instructions. For now modify them
to pass in 0 as a suffix.

Note that at this point no prefixed instructions are emulated or
analysed - this is just making it possible to do so.

Signed-off-by: Jordan Niethe 
---
v2: - Move definition of __get_user_instr() and
__get_user_instr_inatomic() to "powerpc: Support prefixed instructions
in alignment handler."
- Use a macro for returning the length of an op
- Rename sufx -> suffix
- Define and use PPC_NO_SUFFIX instead of 0
---
 arch/powerpc/include/asm/ppc-opcode.h |  5 +
 arch/powerpc/include/asm/sstep.h  |  9 ++--
 arch/powerpc/kernel/align.c   |  2 +-
 arch/powerpc/kernel/hw_breakpoint.c   |  4 ++--
 arch/powerpc/kernel/kprobes.c |  2 +-
 arch/powerpc/kernel/mce_power.c   |  2 +-
 arch/powerpc/kernel/optprobes.c   |  3 ++-
 arch/powerpc/kernel/uprobes.c |  2 +-
 arch/powerpc/kvm/emulate_loadstore.c  |  2 +-
 arch/powerpc/lib/sstep.c  | 12 ++-
 arch/powerpc/lib/test_emulate_step.c  | 30 +--
 arch/powerpc/xmon/xmon.c  |  5 +++--
 12 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index c1df75edde44..72783bc92e50 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -377,6 +377,11 @@
 #define PPC_INST_VCMPEQUD  0x10c7
 #define PPC_INST_VCMPEQUB  0x1006
 
+/* macro to check if a word is a prefix */
+#define IS_PREFIX(x)   (((x) >> 26) == 1)
+#definePPC_NO_SUFFIX   0
+#definePPC_INST_LENGTH(x)  (IS_PREFIX(x) ? 8 : 4)
+
 /* macros to insert fields into opcodes */
 #define ___PPC_RA(a)   (((a) & 0x1f) << 16)
 #define ___PPC_RB(b)   (((b) & 0x1f) << 11)
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 769f055509c9..9ea8904a1549 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -89,11 +89,15 @@ enum instruction_type {
 #define VSX_LDLEFT 4   /* load VSX register from left */
 #define VSX_CHECK_VEC  8   /* check MSR_VEC not MSR_VSX for reg >= 32 */
 
+/* Prefixed flag, ORed in with type */
+#define PREFIXED   0x800
+
 /* Size field in type word */
 #define SIZE(n)((n) << 12)
 #define GETSIZE(w) ((w) >> 12)
 
 #define GETTYPE(t) ((t) & INSTR_TYPE_MASK)
+#define OP_LENGTH(t)   (((t) & PREFIXED) ? 8 : 4)
 
 #define MKOP(t, f, s)  ((t) | (f) | SIZE(s))
 
@@ -132,7 +136,7 @@ union vsx_reg {
  * otherwise.
  */
 extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
-unsigned int instr);
+unsigned int instr, unsigned int suffix);
 
 /*
  * Emulate an instruction that can be executed just by updating
@@ -149,7 +153,8 @@ void emulate_update_regs(struct pt_regs *reg, struct 
instruction_op *op);
  * 0 if it could not be emulated, or -1 for an instruction that
  * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.).
  */
-extern int emulate_step(struct pt_regs *regs, unsigned int instr);
+extern int emulate_step(struct pt_regs *regs, unsigned int instr,
+   unsigned int suffix);
 
 /*
  * Emulate a load or store instruction by reading/writing the
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 92045ed64976..ba3bf5c3ab62 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -334,7 +334,7 @@ int fix_alignment(struct pt_regs *regs)
if ((instr & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe))
return -EIO;
 
-   r = analyse_instr(, regs, instr);
+   r = analyse_instr(, regs, instr, PPC_NO_SUFFIX);
if (r < 0)
return -EINVAL;
 
diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c