linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/16] Initial Prefixed Instruction support
@ 2020-03-20  5:17 Jordan Niethe
  2020-03-20  5:17 ` [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
                   ` (16 more replies)
  0 siblings, 17 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

A future revision of the ISA will introduce prefixed instructions. A
prefixed instruction is composed of a 4-byte prefix followed by a
4-byte suffix.

All prefixes have the major opcode 1. A prefix will never be a valid
word instruction. A suffix may be an existing word instruction or a
new instruction.

This series enables prefixed instructions and extends the instruction
emulation to support them. Then the places where prefixed instructions
might need to be emulated are updated.

The series is based on top of:
https://patchwork.ozlabs.org/patch/1232619/ as this will effect
kprobes.

v4 is based on feedback from Nick Piggins, Christophe Leroy and Daniel Axtens.
The major changes:
    - Move xmon breakpoints from data section to text section
    - Introduce a data type for instructions on powerpc

v3 is based on feedback from Christophe Leroy. The major changes:
    - Completely replacing store_inst() with patch_instruction() in
      xmon
    - Improve implementation of mread_instr() to not use mread().
    - Base the series on top of
      https://patchwork.ozlabs.org/patch/1232619/ as this will effect
      kprobes.
    - Some renaming and simplification of conditionals.

v2 incorporates feedback from Daniel Axtens and and Balamuruhan
S. The major changes are:
    - Squashing together all commits about SRR1 bits
    - Squashing all commits for supporting prefixed load stores
    - Changing abbreviated references to sufx/prfx -> suffix/prefix
    - Introducing macros for returning the length of an instruction
    - Removing sign extension flag from pstd/pld in sstep.c
    - Dropping patch  "powerpc/fault: Use analyse_instr() to check for
      store with updates to sp" from the series, it did not really fit
      with prefixed enablement in the first place and as reported by Greg
      Kurz did not work correctly.

Alistair Popple (1):
  powerpc: Enable Prefixed Instructions

Jordan Niethe (15):
  powerpc/xmon: Remove store_inst() for patch_instruction()
  xmon: Move out-of-line instructions to text section
  powerpc: Use a datatype for instructions
  powerpc: Use a macro for creating instructions from u32s
  powerpc: Use a function for masking instructions
  powerpc: Use a function for getting the instruction op code
  powerpc: Introduce functions for instruction nullity and equality
  powerpc: Use an accessor for word instructions
  powerpc: Use a function for reading instructions
  powerpc: Make test_translate_branch() independent of instruction
    length
  powerpc: Define new SRR1 bits for a future ISA version
  powerpc: Support prefixed instructions in alignment handler
  powerpc64: Add prefixed instructions to instruction data type
  powerpc sstep: Add support for prefixed load/stores
  powerpc sstep: Add support for prefixed fixed-point arithmetic

 arch/powerpc/include/asm/code-patching.h |  33 +-
 arch/powerpc/include/asm/inst.h          | 143 +++++++
 arch/powerpc/include/asm/kprobes.h       |   2 +-
 arch/powerpc/include/asm/reg.h           |   7 +-
 arch/powerpc/include/asm/sstep.h         |  15 +-
 arch/powerpc/include/asm/uaccess.h       |  22 ++
 arch/powerpc/include/asm/uprobes.h       |   6 +-
 arch/powerpc/kernel/align.c              |  13 +-
 arch/powerpc/kernel/hw_breakpoint.c      |   5 +-
 arch/powerpc/kernel/jump_label.c         |   2 +-
 arch/powerpc/kernel/kprobes.c            |  19 +-
 arch/powerpc/kernel/mce_power.c          |   5 +-
 arch/powerpc/kernel/module_64.c          |   2 +-
 arch/powerpc/kernel/optprobes.c          |  68 ++--
 arch/powerpc/kernel/optprobes_head.S     |   3 +
 arch/powerpc/kernel/security.c           |   8 +-
 arch/powerpc/kernel/trace/ftrace.c       | 179 +++++----
 arch/powerpc/kernel/traps.c              |  22 +-
 arch/powerpc/kernel/uprobes.c            |   4 +-
 arch/powerpc/kernel/vmlinux.lds.S        |   2 +-
 arch/powerpc/kvm/book3s_hv_nested.c      |   2 +-
 arch/powerpc/kvm/book3s_hv_rm_mmu.c      |   2 +-
 arch/powerpc/kvm/emulate_loadstore.c     |   3 +-
 arch/powerpc/lib/code-patching.c         | 184 ++++-----
 arch/powerpc/lib/feature-fixups.c        |  47 +--
 arch/powerpc/lib/sstep.c                 | 455 ++++++++++++++++-------
 arch/powerpc/lib/test_emulate_step.c     |  56 +--
 arch/powerpc/xmon/xmon.c                 |  93 +++--
 28 files changed, 925 insertions(+), 477 deletions(-)
 create mode 100644 arch/powerpc/include/asm/inst.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction()
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
@ 2020-03-20  5:17 ` Jordan Niethe
  2020-03-23  6:19   ` Nicholas Piggin
  2020-03-20  5:17 ` [PATCH v4 02/16] xmon: Move out-of-line instructions to text section Jordan Niethe
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

For modifying instructions in xmon, patch_instruction() can serve the
same role that store_inst() is performing with the advantage of not
being specific to xmon. In some places patch_instruction() is already
being using followed by store_inst(). In these cases just remove the
store_inst(). Otherwise replace store_inst() with patch_instruction().

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: Read into a local variable
---
 arch/powerpc/xmon/xmon.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index e8c84d265602..02e3bd62cab4 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -325,11 +325,6 @@ static inline void sync(void)
 	asm volatile("sync; isync");
 }
 
-static inline void store_inst(void *p)
-{
-	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
-}
-
 static inline void cflush(void *p)
 {
 	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
@@ -881,8 +876,7 @@ static struct bpt *new_breakpoint(unsigned long a)
 	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
 			bp->address = a;
-			bp->instr[1] = bpinstr;
-			store_inst(&bp->instr[1]);
+			patch_instruction(&bp->instr[1], bpinstr);
 			return bp;
 		}
 	}
@@ -894,25 +888,26 @@ static struct bpt *new_breakpoint(unsigned long a)
 static void insert_bpts(void)
 {
 	int i;
+	unsigned int instr;
 	struct bpt *bp;
 
 	bp = bpts;
 	for (i = 0; i < NBPTS; ++i, ++bp) {
 		if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
 			continue;
-		if (mread(bp->address, &bp->instr[0], 4) != 4) {
+		if (mread(bp->address, &instr, 4) != 4) {
 			printf("Couldn't read instruction at %lx, "
 			       "disabling breakpoint there\n", bp->address);
 			bp->enabled = 0;
 			continue;
 		}
-		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
+		if (IS_MTMSRD(instr) || IS_RFID(instr)) {
 			printf("Breakpoint at %lx is on an mtmsrd or rfid "
 			       "instruction, disabling it\n", bp->address);
 			bp->enabled = 0;
 			continue;
 		}
-		store_inst(&bp->instr[0]);
+		patch_instruction(bp->instr, instr);
 		if (bp->enabled & BP_CIABR)
 			continue;
 		if (patch_instruction((unsigned int *)bp->address,
@@ -922,7 +917,6 @@ static void insert_bpts(void)
 			bp->enabled &= ~BP_TRAP;
 			continue;
 		}
-		store_inst((void *)bp->address);
 	}
 }
 
@@ -957,8 +951,6 @@ static void remove_bpts(void)
 			(unsigned int *)bp->address, bp->instr[0]) != 0)
 			printf("Couldn't remove breakpoint at %lx\n",
 			       bp->address);
-		else
-			store_inst((void *)bp->address);
 	}
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 02/16] xmon: Move out-of-line instructions to text section
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
  2020-03-20  5:17 ` [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
@ 2020-03-20  5:17 ` Jordan Niethe
  2020-03-23  5:59   ` Balamuruhan S
                     ` (2 more replies)
  2020-03-20  5:17 ` [PATCH v4 03/16] powerpc: Use a datatype for instructions Jordan Niethe
                   ` (14 subsequent siblings)
  16 siblings, 3 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

To execute an instruction out of line after a breakpoint, the NIP is set
to the address of struct bpt::instr. Here a copy of the instruction that
was replaced with a breakpoint is kept, along with a trap so normal flow
can be resumed after XOLing. The struct bpt's are located within the
data section. This is problematic as the data section may be marked as
no execute.

Instead of each struct bpt holding the instructions to be XOL'd, make a
new array, bpt_table[], with enough space to hold instructions for the
number of supported breakpoints. Place this array in the text section.
Make struct bpt::instr a pointer to the instructions in bpt_table[]
associated with that breakpoint. This association is a simple mapping:
bpts[n] -> bpt_table[n * words per breakpoint]. Currently we only need
the copied instruction followed by a trap, so 2 words per breakpoint.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/kernel/vmlinux.lds.S |  2 +-
 arch/powerpc/xmon/xmon.c          | 22 +++++++++++++---------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index b4c89a1acebb..e90845b8c300 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -86,7 +86,7 @@ SECTIONS
 		ALIGN_FUNCTION();
 #endif
 		/* careful! __ftr_alt_* sections need to be close to .text */
-		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text);
+		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text .text.xmon_bpts);
 #ifdef CONFIG_PPC64
 		*(.tramp.ftrace.text);
 #endif
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 02e3bd62cab4..7875d1a37770 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -97,7 +97,7 @@ static long *xmon_fault_jmp[NR_CPUS];
 /* Breakpoint stuff */
 struct bpt {
 	unsigned long	address;
-	unsigned int	instr[2];
+	unsigned int	*instr;
 	atomic_t	ref_count;
 	int		enabled;
 	unsigned long	pad;
@@ -109,6 +109,7 @@ struct bpt {
 #define BP_DABR		4
 
 #define NBPTS	256
+#define BPT_WORDS	2
 static struct bpt bpts[NBPTS];
 static struct bpt dabr;
 static struct bpt *iabr;
@@ -116,6 +117,8 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
 
 #define BP_NUM(bp)	((bp) - bpts + 1)
 
+static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS];
+
 /* Prototypes */
 static int cmds(struct pt_regs *);
 static int mread(unsigned long, void *, int);
@@ -852,16 +855,16 @@ static struct bpt *at_breakpoint(unsigned long pc)
 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
 {
 	unsigned long off;
+	unsigned long bp_off;
 
-	off = nip - (unsigned long) bpts;
-	if (off >= sizeof(bpts))
+	off = nip - (unsigned long) bpt_table;
+	if (off >= sizeof(bpt_table))
 		return NULL;
-	off %= sizeof(struct bpt);
-	if (off != offsetof(struct bpt, instr[0])
-	    && off != offsetof(struct bpt, instr[1]))
+	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
+	if (bp_off != 0 && bp_off != 4)
 		return NULL;
-	*offp = off - offsetof(struct bpt, instr[0]);
-	return (struct bpt *) (nip - off);
+	*offp = bp_off;
+	return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
 }
 
 static struct bpt *new_breakpoint(unsigned long a)
@@ -876,7 +879,8 @@ static struct bpt *new_breakpoint(unsigned long a)
 	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
 			bp->address = a;
-			patch_instruction(&bp->instr[1], bpinstr);
+			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
+			patch_instruction(bp->instr + 1, bpinstr);
 			return bp;
 		}
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
  2020-03-20  5:17 ` [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
  2020-03-20  5:17 ` [PATCH v4 02/16] xmon: Move out-of-line instructions to text section Jordan Niethe
@ 2020-03-20  5:17 ` Jordan Niethe
  2020-03-23  6:07   ` Balamuruhan S
                     ` (2 more replies)
  2020-03-20  5:17 ` [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
                   ` (13 subsequent siblings)
  16 siblings, 3 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Currently unsigned ints are used to represent instructions on powerpc.
This has worked well as instructions have always been 4 byte words.
However, a future ISA version will introduce some changes to
instructions that mean this scheme will no longer work as well. This
change is Prefixed Instructions. A prefixed instruction is made up of a
word prefix followed by a word suffix to make an 8 byte double word
instruction. No matter the endianess of the system the prefix always
comes first. Prefixed instructions are only planned for powerpc64.

Introduce a ppc_inst type to represent both prefixed and word
instructions on powerpc64 while keeping it possible to exclusively have
word instructions on powerpc32, A latter patch will expand the type to
include prefixed instructions but for now just typedef it to a u32.

Later patches will introduce helper functions and macros for
manipulating the instructions so that powerpc64 and powerpc32 might
maintain separate type definitions.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/include/asm/code-patching.h | 31 +++++------
 arch/powerpc/include/asm/inst.h          | 53 +++++++++++++++++++
 arch/powerpc/include/asm/sstep.h         |  5 +-
 arch/powerpc/kernel/align.c              |  2 +-
 arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
 arch/powerpc/kernel/kprobes.c            |  2 +-
 arch/powerpc/kernel/mce_power.c          |  5 +-
 arch/powerpc/kernel/optprobes.c          | 10 ++--
 arch/powerpc/kernel/trace/ftrace.c       | 66 ++++++++++++------------
 arch/powerpc/kvm/emulate_loadstore.c     |  1 +
 arch/powerpc/lib/code-patching.c         | 54 +++++++++----------
 arch/powerpc/lib/sstep.c                 |  4 +-
 arch/powerpc/lib/test_emulate_step.c     |  9 ++--
 arch/powerpc/xmon/xmon.c                 | 12 ++---
 14 files changed, 160 insertions(+), 97 deletions(-)
 create mode 100644 arch/powerpc/include/asm/inst.h

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 898b54262881..cb5106f92d67 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -11,6 +11,7 @@
 #include <linux/string.h>
 #include <linux/kallsyms.h>
 #include <asm/asm-compat.h>
+#include <asm/inst.h>
 
 /* Flags for create_branch:
  * "b"   == create_branch(addr, target, 0);
@@ -22,27 +23,27 @@
 #define BRANCH_ABSOLUTE	0x2
 
 bool is_offset_in_branch_range(long offset);
-unsigned int create_branch(const unsigned int *addr,
+ppc_inst create_branch(const ppc_inst *addr,
 			   unsigned long target, int flags);
-unsigned int create_cond_branch(const unsigned int *addr,
+unsigned int create_cond_branch(const ppc_inst *addr,
 				unsigned long target, int flags);
-int patch_branch(unsigned int *addr, unsigned long target, int flags);
-int patch_instruction(unsigned int *addr, unsigned int instr);
-int raw_patch_instruction(unsigned int *addr, unsigned int instr);
+int patch_branch(ppc_inst *addr, unsigned long target, int flags);
+int patch_instruction(ppc_inst *addr, ppc_inst instr);
+int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
 
 static inline unsigned long patch_site_addr(s32 *site)
 {
 	return (unsigned long)site + *site;
 }
 
-static inline int patch_instruction_site(s32 *site, unsigned int instr)
+static inline int patch_instruction_site(s32 *site, ppc_inst instr)
 {
-	return patch_instruction((unsigned int *)patch_site_addr(site), instr);
+	return patch_instruction((ppc_inst *)patch_site_addr(site), instr);
 }
 
 static inline int patch_branch_site(s32 *site, unsigned long target, int flags)
 {
-	return patch_branch((unsigned int *)patch_site_addr(site), target, flags);
+	return patch_branch((ppc_inst *)patch_site_addr(site), target, flags);
 }
 
 static inline int modify_instruction(unsigned int *addr, unsigned int clr,
@@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
 	return modify_instruction((unsigned int *)patch_site_addr(site), clr, set);
 }
 
-int instr_is_relative_branch(unsigned int instr);
-int instr_is_relative_link_branch(unsigned int instr);
-int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
-unsigned long branch_target(const unsigned int *instr);
-unsigned int translate_branch(const unsigned int *dest,
-			      const unsigned int *src);
-extern bool is_conditional_branch(unsigned int instr);
+int instr_is_relative_branch(ppc_inst instr);
+int instr_is_relative_link_branch(ppc_inst instr);
+int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
+unsigned long branch_target(const ppc_inst *instr);
+ppc_inst translate_branch(const ppc_inst *dest,
+			      const ppc_inst *src);
+extern bool is_conditional_branch(ppc_inst instr);
 #ifdef CONFIG_PPC_BOOK3E_64
 void __patch_exception(int exc, unsigned long addr);
 #define patch_exception(exc, name) do { \
diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
new file mode 100644
index 000000000000..7c8596ee411e
--- /dev/null
+++ b/arch/powerpc/include/asm/inst.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _ASM_INST_H
+#define _ASM_INST_H
+
+/*
+ * Instruction data type for POWER
+ */
+
+typedef u32 ppc_inst;
+
+#define PPC_INST(x) (x)
+
+static inline int ppc_inst_len(ppc_inst x)
+{
+	return sizeof(ppc_inst);
+}
+
+static inline int ppc_inst_opcode(ppc_inst x)
+{
+	return x >> 26;
+}
+
+static inline u32 ppc_inst_word(ppc_inst x)
+{
+	return x;
+}
+
+static inline ppc_inst ppc_inst_read(const ppc_inst *ptr)
+{
+	return *(ppc_inst *)ptr;
+}
+
+static inline void ppc_inst_write(void *ptr, ppc_inst x)
+{
+	*(ppc_inst *)ptr = x;
+}
+
+static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
+{
+	return x == y;
+}
+
+static inline bool ppc_inst_null(ppc_inst x)
+{
+	return x == 0;
+}
+
+static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
+{
+	return ppc_inst_word(x) & mask;
+}
+
+#endif /* _ASM_INST_H */
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 769f055509c9..9353916fcba7 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
  */
+#include <asm/inst.h>
 
 struct pt_regs;
 
@@ -132,7 +133,7 @@ union vsx_reg {
  * otherwise.
  */
 extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
-			 unsigned int instr);
+			 ppc_inst instr);
 
 /*
  * Emulate an instruction that can be executed just by updating
@@ -149,7 +150,7 @@ 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, ppc_inst instr);
 
 /*
  * 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..34594aaa44de 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -293,7 +293,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
 
 int fix_alignment(struct pt_regs *regs)
 {
-	unsigned int instr;
+	ppc_inst instr;
 	struct instruction_op op;
 	int r, type;
 
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 2462cd7c565c..06b97353d231 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -24,6 +24,7 @@
 #include <asm/debug.h>
 #include <asm/debugfs.h>
 #include <asm/hvcall.h>
+#include <asm/inst.h>
 #include <linux/uaccess.h>
 
 /*
@@ -243,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size, struct arch_hw_breakpoint *info)
 static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
 			     struct arch_hw_breakpoint *info)
 {
-	unsigned int instr = 0;
+	ppc_inst instr = 0;
 	int ret, type, size;
 	struct instruction_op op;
 	unsigned long addr = info->address;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 337516df17d4..e7205adc9820 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
 static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
 {
 	int ret;
-	unsigned int insn = *p->ainsn.insn;
+	ppc_inst insn = *p->ainsn.insn;
 
 	/* regs->nip is also adjusted if emulate_step returns 1 */
 	ret = emulate_step(regs, insn);
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index 1cbf7f1a4e3d..e65616bb3a3e 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -20,6 +20,7 @@
 #include <asm/sstep.h>
 #include <asm/exception-64s.h>
 #include <asm/extable.h>
+#include <asm/inst.h>
 
 /*
  * Convert an address related to an mm to a PFN. NOTE: we are in real
@@ -365,7 +366,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
 	 * in real-mode is tricky and can lead to recursive
 	 * faults
 	 */
-	int instr;
+	ppc_inst instr;
 	unsigned long pfn, instr_addr;
 	struct instruction_op op;
 	struct pt_regs tmp = *regs;
@@ -373,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
 	pfn = addr_to_pfn(regs, regs->nip);
 	if (pfn != ULONG_MAX) {
 		instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
-		instr = *(unsigned int *)(instr_addr);
+		instr = *(ppc_inst *)(instr_addr);
 		if (!analyse_instr(&op, &tmp, instr)) {
 			pfn = addr_to_pfn(regs, op.ea);
 			*addr = op.ea;
diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index 024f7aad1952..f5e8cce438a3 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -189,8 +189,8 @@ void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
 
 int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 {
-	kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
-	kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
+	ppc_inst branch_op_callback, branch_emulate_step;
+	kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
 	long b_offset;
 	unsigned long nip, size;
 	int rc, i;
@@ -251,11 +251,11 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 		goto error;
 	}
 
-	branch_op_callback = create_branch((unsigned int *)buff + TMPL_CALL_HDLR_IDX,
+	branch_op_callback = create_branch((ppc_inst *)buff + TMPL_CALL_HDLR_IDX,
 				(unsigned long)op_callback_addr,
 				BRANCH_SET_LINK);
 
-	branch_emulate_step = create_branch((unsigned int *)buff + TMPL_EMULATE_IDX,
+	branch_emulate_step = create_branch((ppc_inst *)buff + TMPL_EMULATE_IDX,
 				(unsigned long)emulate_step_addr,
 				BRANCH_SET_LINK);
 
@@ -316,7 +316,7 @@ void arch_optimize_kprobes(struct list_head *oplist)
 		memcpy(op->optinsn.copied_insn, op->kp.addr,
 					       RELATIVEJUMP_SIZE);
 		patch_instruction(op->kp.addr,
-			create_branch((unsigned int *)op->kp.addr,
+			create_branch((ppc_inst *)op->kp.addr,
 				      (unsigned long)op->optinsn.insn, 0));
 		list_del_init(&op->list);
 	}
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 7ea0ca044b65..5787ccffb4df 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -27,6 +27,7 @@
 #include <asm/code-patching.h>
 #include <asm/ftrace.h>
 #include <asm/syscall.h>
+#include <asm/inst.h>
 
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -40,23 +41,23 @@
 #define	NUM_FTRACE_TRAMPS	8
 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
 
-static unsigned int
+static ppc_inst
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
-	unsigned int op;
+	ppc_inst op;
 
 	addr = ppc_function_entry((void *)addr);
 
 	/* if (link) set op to 'bl' else 'b' */
-	op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
+	op = create_branch((ppc_inst *)ip, addr, link ? 1 : 0);
 
 	return op;
 }
 
 static int
-ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
+ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
 {
-	unsigned int replaced;
+	ppc_inst replaced;
 
 	/*
 	 * Note:
@@ -78,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
 	}
 
 	/* replace the text with the new text */
-	if (patch_instruction((unsigned int *)ip, new))
+	if (patch_instruction((ppc_inst *)ip, new))
 		return -EPERM;
 
 	return 0;
@@ -87,25 +88,25 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
 /*
  * Helper functions that are the same for both PPC64 and PPC32.
  */
-static int test_24bit_addr(unsigned long ip, unsigned long addr)
+static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr)
 {
 	addr = ppc_function_entry((void *)addr);
 
 	/* use the create_branch to verify that this offset can be branched */
-	return create_branch((unsigned int *)ip, addr, 0);
+	return create_branch((ppc_inst *)ip, addr, 0);
 }
 
-static int is_bl_op(unsigned int op)
+static int is_bl_op(ppc_inst op)
 {
 	return (op & 0xfc000003) == 0x48000001;
 }
 
-static int is_b_op(unsigned int op)
+static int is_b_op(ppc_inst op)
 {
 	return (op & 0xfc000003) == 0x48000000;
 }
 
-static unsigned long find_bl_target(unsigned long ip, unsigned int op)
+static unsigned long find_bl_target(unsigned long ip, ppc_inst op)
 {
 	int offset;
 
@@ -125,7 +126,7 @@ __ftrace_make_nop(struct module *mod,
 {
 	unsigned long entry, ptr, tramp;
 	unsigned long ip = rec->ip;
-	unsigned int op, pop;
+	ppc_inst op, pop;
 
 	/* read where this goes */
 	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
@@ -204,7 +205,7 @@ __ftrace_make_nop(struct module *mod,
 	}
 #endif /* CONFIG_MPROFILE_KERNEL */
 
-	if (patch_instruction((unsigned int *)ip, pop)) {
+	if (patch_instruction((ppc_inst *)ip, pop)) {
 		pr_err("Patching NOP failed.\n");
 		return -EPERM;
 	}
@@ -217,7 +218,7 @@ static int
 __ftrace_make_nop(struct module *mod,
 		  struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned int op;
+	ppc_inst op;
 	unsigned int jmp[4];
 	unsigned long ip = rec->ip;
 	unsigned long tramp;
@@ -276,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
 
 	op = PPC_INST_NOP;
 
-	if (patch_instruction((unsigned int *)ip, op))
+	if (patch_instruction((ppc_inst *)ip, op))
 		return -EPERM;
 
 	return 0;
@@ -322,7 +323,8 @@ static int add_ftrace_tramp(unsigned long tramp)
  */
 static int setup_mcount_compiler_tramp(unsigned long tramp)
 {
-	int i, op;
+	int i;
+	ppc_inst op;
 	unsigned long ptr;
 	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
 
@@ -388,7 +390,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
 static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 {
 	unsigned long tramp, ip = rec->ip;
-	unsigned int op;
+	ppc_inst op;
 
 	/* Read where this goes */
 	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
@@ -416,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 		}
 	}
 
-	if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) {
+	if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) {
 		pr_err("Patching NOP failed.\n");
 		return -EPERM;
 	}
@@ -428,7 +430,7 @@ int ftrace_make_nop(struct module *mod,
 		    struct dyn_ftrace *rec, unsigned long addr)
 {
 	unsigned long ip = rec->ip;
-	unsigned int old, new;
+	ppc_inst old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -481,7 +483,7 @@ int ftrace_make_nop(struct module *mod,
  */
 #ifndef CONFIG_MPROFILE_KERNEL
 static int
-expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
+expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
 {
 	/*
 	 * We expect to see:
@@ -510,7 +512,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
 static int
 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned int op[2];
+	ppc_inst op[2];
 	void *ip = (void *)rec->ip;
 	unsigned long entry, ptr, tramp;
 	struct module *mod = rec->arch.mod;
@@ -574,7 +576,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 static int
 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned int op;
+	ppc_inst op;
 	unsigned long ip = rec->ip;
 
 	/* read where this goes */
@@ -594,7 +596,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	/* create the branch to the trampoline */
-	op = create_branch((unsigned int *)ip,
+	op = create_branch((ppc_inst *)ip,
 			   rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
 	if (!op) {
 		pr_err("REL24 out of range!\n");
@@ -613,7 +615,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 
 static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned int op;
+	ppc_inst op;
 	void *ip = (void *)rec->ip;
 	unsigned long tramp, entry, ptr;
 
@@ -661,7 +663,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
 	unsigned long ip = rec->ip;
-	unsigned int old, new;
+	ppc_inst old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -700,7 +702,7 @@ static int
 __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 					unsigned long addr)
 {
-	unsigned int op;
+	ppc_inst op;
 	unsigned long ip = rec->ip;
 	unsigned long entry, ptr, tramp;
 	struct module *mod = rec->arch.mod;
@@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	/* The new target may be within range */
 	if (test_24bit_addr(ip, addr)) {
 		/* within range */
-		if (patch_branch((unsigned int *)ip, addr, BRANCH_SET_LINK)) {
+		if (patch_branch((ppc_inst *)ip, addr, BRANCH_SET_LINK)) {
 			pr_err("REL24 out of range!\n");
 			return -EINVAL;
 		}
@@ -776,7 +778,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	}
 
 	/* Ensure branch is within 24 bits */
-	if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
+	if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
@@ -794,7 +796,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 			unsigned long addr)
 {
 	unsigned long ip = rec->ip;
-	unsigned int old, new;
+	ppc_inst old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -834,7 +836,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 int ftrace_update_ftrace_func(ftrace_func_t func)
 {
 	unsigned long ip = (unsigned long)(&ftrace_call);
-	unsigned int old, new;
+	ppc_inst old, new;
 	int ret;
 
 	old = *(unsigned int *)&ftrace_call;
@@ -919,7 +921,7 @@ int ftrace_enable_ftrace_graph_caller(void)
 	unsigned long ip = (unsigned long)(&ftrace_graph_call);
 	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
 	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
-	unsigned int old, new;
+	ppc_inst old, new;
 
 	old = ftrace_call_replace(ip, stub, 0);
 	new = ftrace_call_replace(ip, addr, 0);
@@ -932,7 +934,7 @@ int ftrace_disable_ftrace_graph_caller(void)
 	unsigned long ip = (unsigned long)(&ftrace_graph_call);
 	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
 	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
-	unsigned int old, new;
+	ppc_inst old, new;
 
 	old = ftrace_call_replace(ip, addr, 0);
 	new = ftrace_call_replace(ip, stub, 0);
diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c
index 1139bc56e004..1c9bcbfeb924 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -21,6 +21,7 @@
 #include <asm/disassemble.h>
 #include <asm/ppc-opcode.h>
 #include <asm/sstep.h>
+#include <asm/inst.h>
 #include "timing.h"
 #include "trace.h"
 
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 3345f039a876..8492b9e2b8db 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -17,9 +17,10 @@
 #include <asm/page.h>
 #include <asm/code-patching.h>
 #include <asm/setup.h>
+#include <asm/inst.h>
 
-static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
-			       unsigned int *patch_addr)
+static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
+			       ppc_inst *patch_addr)
 {
 	int err = 0;
 
@@ -33,7 +34,7 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
 	return 0;
 }
 
-int raw_patch_instruction(unsigned int *addr, unsigned int instr)
+int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
 {
 	return __patch_instruction(addr, instr, addr);
 }
@@ -136,10 +137,10 @@ static inline int unmap_patch_area(unsigned long addr)
 	return 0;
 }
 
-static int do_patch_instruction(unsigned int *addr, unsigned int instr)
+static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
 {
 	int err;
-	unsigned int *patch_addr = NULL;
+	ppc_inst *patch_addr = NULL;
 	unsigned long flags;
 	unsigned long text_poke_addr;
 	unsigned long kaddr = (unsigned long)addr;
@@ -176,7 +177,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
 }
 #else /* !CONFIG_STRICT_KERNEL_RWX */
 
-static int do_patch_instruction(unsigned int *addr, unsigned int instr)
+static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
 {
 	return raw_patch_instruction(addr, instr);
 }
@@ -194,7 +195,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
 }
 NOKPROBE_SYMBOL(patch_instruction);
 
-int patch_branch(unsigned int *addr, unsigned long target, int flags)
+int patch_branch(ppc_inst *addr, unsigned long target, int flags)
 {
 	return patch_instruction(addr, create_branch(addr, target, flags));
 }
@@ -225,7 +226,7 @@ bool is_offset_in_branch_range(long offset)
  * Helper to check if a given instruction is a conditional branch
  * Derived from the conditional checks in analyse_instr()
  */
-bool is_conditional_branch(unsigned int instr)
+bool is_conditional_branch(ppc_inst instr)
 {
 	unsigned int opcode = instr >> 26;
 
@@ -243,10 +244,10 @@ bool is_conditional_branch(unsigned int instr)
 }
 NOKPROBE_SYMBOL(is_conditional_branch);
 
-unsigned int create_branch(const unsigned int *addr,
+ppc_inst create_branch(const ppc_inst *addr,
 			   unsigned long target, int flags)
 {
-	unsigned int instruction;
+	ppc_inst instruction;
 	long offset;
 
 	offset = target;
@@ -266,7 +267,7 @@ unsigned int create_branch(const unsigned int *addr,
 unsigned int create_cond_branch(const unsigned int *addr,
 				unsigned long target, int flags)
 {
-	unsigned int instruction;
+	ppc_inst instruction;
 	long offset;
 
 	offset = target;
@@ -283,22 +284,22 @@ unsigned int create_cond_branch(const unsigned int *addr,
 	return instruction;
 }
 
-static unsigned int branch_opcode(unsigned int instr)
+static unsigned int branch_opcode(ppc_inst instr)
 {
 	return (instr >> 26) & 0x3F;
 }
 
-static int instr_is_branch_iform(unsigned int instr)
+static int instr_is_branch_iform(ppc_inst instr)
 {
 	return branch_opcode(instr) == 18;
 }
 
-static int instr_is_branch_bform(unsigned int instr)
+static int instr_is_branch_bform(ppc_inst instr)
 {
 	return branch_opcode(instr) == 16;
 }
 
-int instr_is_relative_branch(unsigned int instr)
+int instr_is_relative_branch(ppc_inst instr)
 {
 	if (instr & BRANCH_ABSOLUTE)
 		return 0;
@@ -306,12 +307,12 @@ int instr_is_relative_branch(unsigned int instr)
 	return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
 }
 
-int instr_is_relative_link_branch(unsigned int instr)
+int instr_is_relative_link_branch(ppc_inst instr)
 {
 	return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
 }
 
-static unsigned long branch_iform_target(const unsigned int *instr)
+static unsigned long branch_iform_target(const ppc_inst *instr)
 {
 	signed long imm;
 
@@ -327,7 +328,7 @@ static unsigned long branch_iform_target(const unsigned int *instr)
 	return (unsigned long)imm;
 }
 
-static unsigned long branch_bform_target(const unsigned int *instr)
+static unsigned long branch_bform_target(const ppc_inst *instr)
 {
 	signed long imm;
 
@@ -343,7 +344,7 @@ static unsigned long branch_bform_target(const unsigned int *instr)
 	return (unsigned long)imm;
 }
 
-unsigned long branch_target(const unsigned int *instr)
+unsigned long branch_target(const ppc_inst *instr)
 {
 	if (instr_is_branch_iform(*instr))
 		return branch_iform_target(instr);
@@ -353,7 +354,7 @@ unsigned long branch_target(const unsigned int *instr)
 	return 0;
 }
 
-int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
+int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr)
 {
 	if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
 		return branch_target(instr) == addr;
@@ -361,7 +362,7 @@ int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
 	return 0;
 }
 
-unsigned int translate_branch(const unsigned int *dest, const unsigned int *src)
+ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
 {
 	unsigned long target;
 
@@ -403,7 +404,7 @@ static void __init test_trampoline(void)
 
 static void __init test_branch_iform(void)
 {
-	unsigned int instr;
+	ppc_inst instr;
 	unsigned long addr;
 
 	addr = (unsigned long)&instr;
@@ -478,11 +479,11 @@ static void __init test_branch_iform(void)
 
 static void __init test_create_function_call(void)
 {
-	unsigned int *iptr;
+	ppc_inst *iptr;
 	unsigned long dest;
 
 	/* Check we can create a function call */
-	iptr = (unsigned int *)ppc_function_entry(test_trampoline);
+	iptr = (ppc_inst *)ppc_function_entry(test_trampoline);
 	dest = ppc_function_entry(test_create_function_call);
 	patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
 	check(instr_is_branch_to_addr(iptr, dest));
@@ -491,7 +492,8 @@ static void __init test_create_function_call(void)
 static void __init test_branch_bform(void)
 {
 	unsigned long addr;
-	unsigned int *iptr, instr, flags;
+	ppc_inst *iptr, instr;
+	unsigned int flags;
 
 	iptr = &instr;
 	addr = (unsigned long)iptr;
@@ -561,7 +563,7 @@ static void __init test_branch_bform(void)
 static void __init test_translate_branch(void)
 {
 	unsigned long addr;
-	unsigned int *p, *q;
+	ppc_inst *p, *q;
 	void *buf;
 
 	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index c077acb983a1..1d9c766a89fe 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1, long v2)
  * otherwise.
  */
 int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
-		  unsigned int instr)
+		  ppc_inst instr)
 {
 	unsigned int opcode, ra, rb, rc, rd, spr, u;
 	unsigned long int imm;
@@ -3101,7 +3101,7 @@ NOKPROBE_SYMBOL(emulate_loadstore);
  * or -1 if the instruction is one that should not be stepped,
  * such as an rfid, or a mtmsrd that would clear MSR_RI.
  */
-int emulate_step(struct pt_regs *regs, unsigned int instr)
+int emulate_step(struct pt_regs *regs, ppc_inst instr)
 {
 	struct instruction_op op;
 	int r, err, type;
diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c
index 42347067739c..158efc8a0f53 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -460,7 +460,7 @@ struct compute_test {
 	struct {
 		char *descr;
 		unsigned long flags;
-		unsigned int instr;
+		ppc_inst instr;
 		struct pt_regs regs;
 	} subtests[MAX_SUBTESTS + 1];
 };
@@ -841,7 +841,7 @@ static struct compute_test compute_tests[] = {
 };
 
 static int __init emulate_compute_instr(struct pt_regs *regs,
-					unsigned int instr)
+					ppc_inst instr)
 {
 	struct instruction_op op;
 
@@ -859,7 +859,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs,
 }
 
 static int __init execute_compute_instr(struct pt_regs *regs,
-					unsigned int instr)
+					ppc_inst instr)
 {
 	extern int exec_instr(struct pt_regs *regs);
 	extern s32 patch__exec_instr;
@@ -890,7 +890,8 @@ static void __init run_tests_compute(void)
 	unsigned long flags;
 	struct compute_test *test;
 	struct pt_regs *regs, exp, got;
-	unsigned int i, j, k, instr;
+	unsigned int i, j, k;
+	ppc_inst instr;
 	bool ignore_gpr, ignore_xer, ignore_ccr, passed;
 
 	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 7875d1a37770..a0bc442f9557 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
 static void insert_bpts(void)
 {
 	int i;
-	unsigned int instr;
+	ppc_inst instr;
 	struct bpt *bp;
 
 	bp = bpts;
@@ -914,7 +914,7 @@ static void insert_bpts(void)
 		patch_instruction(bp->instr, instr);
 		if (bp->enabled & BP_CIABR)
 			continue;
-		if (patch_instruction((unsigned int *)bp->address,
+		if (patch_instruction((ppc_inst *)bp->address,
 							bpinstr) != 0) {
 			printf("Couldn't write instruction at %lx, "
 			       "disabling breakpoint there\n", bp->address);
@@ -943,7 +943,7 @@ static void remove_bpts(void)
 {
 	int i;
 	struct bpt *bp;
-	unsigned instr;
+	ppc_inst instr;
 
 	bp = bpts;
 	for (i = 0; i < NBPTS; ++i, ++bp) {
@@ -952,7 +952,7 @@ static void remove_bpts(void)
 		if (mread(bp->address, &instr, 4) == 4
 		    && instr == bpinstr
 		    && patch_instruction(
-			(unsigned int *)bp->address, bp->instr[0]) != 0)
+			(ppc_inst *)bp->address, bp->instr[0]) != 0)
 			printf("Couldn't remove breakpoint at %lx\n",
 			       bp->address);
 	}
@@ -1159,7 +1159,7 @@ static int do_step(struct pt_regs *regs)
  */
 static int do_step(struct pt_regs *regs)
 {
-	unsigned int instr;
+	ppc_inst instr;
 	int stepped;
 
 	force_enable_xmon();
@@ -1325,7 +1325,7 @@ csum(void)
  */
 static long check_bp_loc(unsigned long addr)
 {
-	unsigned int instr;
+	ppc_inst instr;
 
 	addr &= ~3;
 	if (!is_kernel_addr(addr)) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (2 preceding siblings ...)
  2020-03-20  5:17 ` [PATCH v4 03/16] powerpc: Use a datatype for instructions Jordan Niethe
@ 2020-03-20  5:17 ` Jordan Niethe
  2020-03-23  6:26   ` Nicholas Piggin
  2020-03-20  5:17 ` [PATCH v4 05/16] powerpc: Use a function for masking instructions Jordan Niethe
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

In preparation for instructions having a more complex data type start
using a macro, PPC_INST(), for making an instruction out of a u32.
Currently this does nothing, but it will allow for creating a data type
that can represent prefixed instructions.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/include/asm/code-patching.h |  2 +-
 arch/powerpc/kernel/align.c              |  2 +-
 arch/powerpc/kernel/hw_breakpoint.c      |  2 +-
 arch/powerpc/kernel/jump_label.c         |  2 +-
 arch/powerpc/kernel/kprobes.c            |  4 +-
 arch/powerpc/kernel/module_64.c          |  2 +-
 arch/powerpc/kernel/optprobes.c          | 30 +++++------
 arch/powerpc/kernel/security.c           |  8 +--
 arch/powerpc/kernel/trace/ftrace.c       | 24 ++++-----
 arch/powerpc/kvm/emulate_loadstore.c     |  2 +-
 arch/powerpc/lib/code-patching.c         | 64 ++++++++++++------------
 arch/powerpc/lib/feature-fixups.c        | 39 ++++++++-------
 arch/powerpc/lib/test_emulate_step.c     | 39 ++++++++-------
 arch/powerpc/xmon/xmon.c                 | 11 ++--
 14 files changed, 117 insertions(+), 114 deletions(-)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index cb5106f92d67..68bd9db334bd 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -49,7 +49,7 @@ static inline int patch_branch_site(s32 *site, unsigned long target, int flags)
 static inline int modify_instruction(unsigned int *addr, unsigned int clr,
 				     unsigned int set)
 {
-	return patch_instruction(addr, (*addr & ~clr) | set);
+	return patch_instruction(addr, PPC_INST((*addr & ~clr) | set));
 }
 
 static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set)
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 34594aaa44de..6008f14a145b 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -309,7 +309,7 @@ int fix_alignment(struct pt_regs *regs)
 		/* We don't handle PPC little-endian any more... */
 		if (cpu_has_feature(CPU_FTR_PPC_LE))
 			return -EIO;
-		instr = swab32(instr);
+		instr = PPC_INST(swab32(instr));
 	}
 
 #ifdef CONFIG_SPE
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 06b97353d231..f001de471b98 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -244,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size, struct arch_hw_breakpoint *info)
 static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
 			     struct arch_hw_breakpoint *info)
 {
-	ppc_inst instr = 0;
+	ppc_inst instr = PPC_INST(0);
 	int ret, type, size;
 	struct instruction_op op;
 	unsigned long addr = info->address;
diff --git a/arch/powerpc/kernel/jump_label.c b/arch/powerpc/kernel/jump_label.c
index ca37702bde97..8d86d1101782 100644
--- a/arch/powerpc/kernel/jump_label.c
+++ b/arch/powerpc/kernel/jump_label.c
@@ -15,5 +15,5 @@ void arch_jump_label_transform(struct jump_entry *entry,
 	if (type == JUMP_LABEL_JMP)
 		patch_branch(addr, entry->target, 0);
 	else
-		patch_instruction(addr, PPC_INST_NOP);
+		patch_instruction(addr, PPC_INST(PPC_INST_NOP));
 }
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index e7205adc9820..4c2b656615a6 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -147,13 +147,13 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
 
 void arch_arm_kprobe(struct kprobe *p)
 {
-	patch_instruction(p->addr, BREAKPOINT_INSTRUCTION);
+	patch_instruction(p->addr, PPC_INST(BREAKPOINT_INSTRUCTION));
 }
 NOKPROBE_SYMBOL(arch_arm_kprobe);
 
 void arch_disarm_kprobe(struct kprobe *p)
 {
-	patch_instruction(p->addr, p->opcode);
+	patch_instruction(p->addr, PPC_INST(p->opcode));
 }
 NOKPROBE_SYMBOL(arch_disarm_kprobe);
 
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 007606a48fd9..fdec1be9cec8 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -506,7 +506,7 @@ static int restore_r2(const char *name, u32 *instruction, struct module *me)
 	 * "link" branches and they don't return, so they don't need the r2
 	 * restore afterwards.
 	 */
-	if (!instr_is_relative_link_branch(*prev_insn))
+	if (!instr_is_relative_link_branch(PPC_INST(*prev_insn)))
 		return 1;
 
 	if (*instruction != PPC_INST_NOP) {
diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index f5e8cce438a3..1025a7a3b3a8 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -147,13 +147,13 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
 void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr)
 {
 	/* addis r4,0,(insn)@h */
-	patch_instruction(addr, PPC_INST_ADDIS | ___PPC_RT(4) |
-			  ((val >> 16) & 0xffff));
+	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(4) |
+			  ((val >> 16) & 0xffff)));
 	addr++;
 
 	/* ori r4,r4,(insn)@l */
-	patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(4) |
-			  ___PPC_RS(4) | (val & 0xffff));
+	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(4) |
+			  ___PPC_RS(4) | (val & 0xffff)));
 }
 
 /*
@@ -163,28 +163,28 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr)
 void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
 {
 	/* lis r3,(op)@highest */
-	patch_instruction(addr, PPC_INST_ADDIS | ___PPC_RT(3) |
-			  ((val >> 48) & 0xffff));
+	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(3) |
+			  ((val >> 48) & 0xffff)));
 	addr++;
 
 	/* ori r3,r3,(op)@higher */
-	patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 32) & 0xffff));
+	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
+			  ___PPC_RS(3) | ((val >> 32) & 0xffff)));
 	addr++;
 
 	/* rldicr r3,r3,32,31 */
-	patch_instruction(addr, PPC_INST_RLDICR | ___PPC_RA(3) |
-			  ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31));
+	patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(3) |
+			  ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)));
 	addr++;
 
 	/* oris r3,r3,(op)@h */
-	patch_instruction(addr, PPC_INST_ORIS | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 16) & 0xffff));
+	patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(3) |
+			  ___PPC_RS(3) | ((val >> 16) & 0xffff)));
 	addr++;
 
 	/* ori r3,r3,(op)@l */
-	patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | (val & 0xffff));
+	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
+			  ___PPC_RS(3) | (val & 0xffff)));
 }
 
 int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
@@ -230,7 +230,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	size = (TMPL_END_IDX * sizeof(kprobe_opcode_t)) / sizeof(int);
 	pr_devel("Copying template to %p, size %lu\n", buff, size);
 	for (i = 0; i < size; i++) {
-		rc = patch_instruction(buff + i, *(optprobe_template_entry + i));
+		rc = patch_instruction(buff + i, PPC_INST(*(optprobe_template_entry + i)));
 		if (rc < 0)
 			goto error;
 	}
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
index bd70f5be1c27..693c68e2aa67 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -403,9 +403,9 @@ static void toggle_count_cache_flush(bool enable)
 		enable = false;
 
 	if (!enable) {
-		patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP);
+		patch_instruction_site(&patch__call_flush_count_cache, PPC_INST(PPC_INST_NOP));
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
-		patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST_NOP);
+		patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST(PPC_INST_NOP));
 #endif
 		pr_info("link-stack-flush: software flush disabled.\n");
 		link_stack_flush_enabled = false;
@@ -428,7 +428,7 @@ static void toggle_count_cache_flush(bool enable)
 
 	// If we just need to flush the link stack, patch an early return
 	if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
-		patch_instruction_site(&patch__flush_link_stack_return, PPC_INST_BLR);
+		patch_instruction_site(&patch__flush_link_stack_return, PPC_INST(PPC_INST_BLR));
 		no_count_cache_flush();
 		return;
 	}
@@ -439,7 +439,7 @@ static void toggle_count_cache_flush(bool enable)
 		return;
 	}
 
-	patch_instruction_site(&patch__flush_count_cache_return, PPC_INST_BLR);
+	patch_instruction_site(&patch__flush_count_cache_return, PPC_INST(PPC_INST_BLR));
 	count_cache_flush_type = COUNT_CACHE_FLUSH_HW;
 	pr_info("count-cache-flush: hardware assisted flush sequence enabled\n");
 }
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 5787ccffb4df..380f1ce77715 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -161,7 +161,7 @@ __ftrace_make_nop(struct module *mod,
 
 #ifdef CONFIG_MPROFILE_KERNEL
 	/* When using -mkernel_profile there is no load to jump over */
-	pop = PPC_INST_NOP;
+	pop = PPC_INST(PPC_INST_NOP);
 
 	if (probe_kernel_read(&op, (void *)(ip - 4), 4)) {
 		pr_err("Fetching instruction at %lx failed.\n", ip - 4);
@@ -169,7 +169,7 @@ __ftrace_make_nop(struct module *mod,
 	}
 
 	/* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
-	if (op != PPC_INST_MFLR && op != PPC_INST_STD_LR) {
+	if (op != PPC_INST(PPC_INST_MFLR) && op != PPC_INST(PPC_INST_STD_LR)) {
 		pr_err("Unexpected instruction %08x around bl _mcount\n", op);
 		return -EINVAL;
 	}
@@ -188,7 +188,7 @@ __ftrace_make_nop(struct module *mod,
 	 * Use a b +8 to jump over the load.
 	 */
 
-	pop = PPC_INST_BRANCH | 8;	/* b +8 */
+	pop = PPC_INST(PPC_INST_BRANCH | 8);	/* b +8 */
 
 	/*
 	 * Check what is in the next instruction. We can see ld r2,40(r1), but
@@ -199,7 +199,7 @@ __ftrace_make_nop(struct module *mod,
 		return -EFAULT;
 	}
 
-	if (op != PPC_INST_LD_TOC) {
+	if (op != PPC_INST(PPC_INST_LD_TOC)) {
 		pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op);
 		return -EINVAL;
 	}
@@ -275,7 +275,7 @@ __ftrace_make_nop(struct module *mod,
 		return -EINVAL;
 	}
 
-	op = PPC_INST_NOP;
+	op = PPC_INST(PPC_INST_NOP);
 
 	if (patch_instruction((ppc_inst *)ip, op))
 		return -EPERM;
@@ -418,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 		}
 	}
 
-	if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) {
+	if (patch_instruction((ppc_inst *)ip, PPC_INST(PPC_INST_NOP))) {
 		pr_err("Patching NOP failed.\n");
 		return -EPERM;
 	}
@@ -440,7 +440,7 @@ int ftrace_make_nop(struct module *mod,
 	if (test_24bit_addr(ip, addr)) {
 		/* within range */
 		old = ftrace_call_replace(ip, addr, 1);
-		new = PPC_INST_NOP;
+		new = PPC_INST(PPC_INST_NOP);
 		return ftrace_modify_code(ip, old, new);
 	} else if (core_kernel_text(ip))
 		return __ftrace_make_nop_kernel(rec, addr);
@@ -500,10 +500,10 @@ expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
 }
 #else
 static int
-expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
+expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
 {
 	/* look for patched "NOP" on ppc64 with -mprofile-kernel */
-	if (op0 != PPC_INST_NOP)
+	if (op0 != PPC_INST(PPC_INST_NOP))
 		return 0;
 	return 1;
 }
@@ -584,7 +584,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 		return -EFAULT;
 
 	/* It should be pointing to a nop */
-	if (op != PPC_INST_NOP) {
+	if (op != PPC_INST(PPC_INST_NOP)) {
 		pr_err("Expected NOP but have %x\n", op);
 		return -EINVAL;
 	}
@@ -641,7 +641,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 		return -EFAULT;
 	}
 
-	if (op != PPC_INST_NOP) {
+	if (op != PPC_INST(PPC_INST_NOP)) {
 		pr_err("Unexpected call sequence at %p: %x\n", ip, op);
 		return -EINVAL;
 	}
@@ -672,7 +672,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	 */
 	if (test_24bit_addr(ip, addr)) {
 		/* within range */
-		old = PPC_INST_NOP;
+		old = PPC_INST(PPC_INST_NOP);
 		new = ftrace_call_replace(ip, addr, 1);
 		return ftrace_modify_code(ip, old, new);
 	} else if (core_kernel_text(ip))
diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c
index 1c9bcbfeb924..ed8cd109f884 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -96,7 +96,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
 
 	emulated = EMULATE_FAIL;
 	vcpu->arch.regs.msr = vcpu->arch.shared->msr;
-	if (analyse_instr(&op, &vcpu->arch.regs, inst) == 0) {
+	if (analyse_instr(&op, &vcpu->arch.regs, PPC_INST(inst)) == 0) {
 		int type = op.type & INSTR_TYPE_MASK;
 		int size = GETSIZE(op.type);
 
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 8492b9e2b8db..5d69e836337d 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -256,10 +256,10 @@ ppc_inst create_branch(const ppc_inst *addr,
 
 	/* Check we can represent the target in the instruction format */
 	if (!is_offset_in_branch_range(offset))
-		return 0;
+		return PPC_INST(0);
 
 	/* Mask out the flags and target, so they don't step on each other. */
-	instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
+	instruction = PPC_INST(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC));
 
 	return instruction;
 }
@@ -276,10 +276,10 @@ unsigned int create_cond_branch(const unsigned int *addr,
 
 	/* Check we can represent the target in the instruction format */
 	if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3)
-		return 0;
+		return PPC_INST(0);
 
 	/* Mask out the flags and target, so they don't step on each other. */
-	instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
+	instruction = PPC_INST(0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC));
 
 	return instruction;
 }
@@ -373,7 +373,7 @@ ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
 	else if (instr_is_branch_bform(*src))
 		return create_cond_branch(dest, target, *src);
 
-	return 0;
+	return PPC_INST(0);
 }
 
 #ifdef CONFIG_PPC_BOOK3E_64
@@ -410,37 +410,37 @@ static void __init test_branch_iform(void)
 	addr = (unsigned long)&instr;
 
 	/* The simplest case, branch to self, no flags */
-	check(instr_is_branch_iform(0x48000000));
+	check(instr_is_branch_iform(PPC_INST(0x48000000)));
 	/* All bits of target set, and flags */
-	check(instr_is_branch_iform(0x4bffffff));
+	check(instr_is_branch_iform(PPC_INST(0x4bffffff)));
 	/* High bit of opcode set, which is wrong */
-	check(!instr_is_branch_iform(0xcbffffff));
+	check(!instr_is_branch_iform(PPC_INST(0xcbffffff)));
 	/* Middle bits of opcode set, which is wrong */
-	check(!instr_is_branch_iform(0x7bffffff));
+	check(!instr_is_branch_iform(PPC_INST(0x7bffffff)));
 
 	/* Simplest case, branch to self with link */
-	check(instr_is_branch_iform(0x48000001));
+	check(instr_is_branch_iform(PPC_INST(0x48000001)));
 	/* All bits of targets set */
-	check(instr_is_branch_iform(0x4bfffffd));
+	check(instr_is_branch_iform(PPC_INST(0x4bfffffd)));
 	/* Some bits of targets set */
-	check(instr_is_branch_iform(0x4bff00fd));
+	check(instr_is_branch_iform(PPC_INST(0x4bff00fd)));
 	/* Must be a valid branch to start with */
-	check(!instr_is_branch_iform(0x7bfffffd));
+	check(!instr_is_branch_iform(PPC_INST(0x7bfffffd)));
 
 	/* Absolute branch to 0x100 */
-	instr = 0x48000103;
+	instr = PPC_INST(0x48000103);
 	check(instr_is_branch_to_addr(&instr, 0x100));
 	/* Absolute branch to 0x420fc */
-	instr = 0x480420ff;
+	instr = PPC_INST(0x480420ff);
 	check(instr_is_branch_to_addr(&instr, 0x420fc));
 	/* Maximum positive relative branch, + 20MB - 4B */
-	instr = 0x49fffffc;
+	instr = PPC_INST(0x49fffffc);
 	check(instr_is_branch_to_addr(&instr, addr + 0x1FFFFFC));
 	/* Smallest negative relative branch, - 4B */
-	instr = 0x4bfffffc;
+	instr = PPC_INST(0x4bfffffc);
 	check(instr_is_branch_to_addr(&instr, addr - 4));
 	/* Largest negative relative branch, - 32 MB */
-	instr = 0x4a000000;
+	instr = PPC_INST(0x4a000000);
 	check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
 
 	/* Branch to self, with link */
@@ -474,7 +474,7 @@ static void __init test_branch_iform(void)
 	/* Check flags are masked correctly */
 	instr = create_branch(&instr, addr, 0xFFFFFFFC);
 	check(instr_is_branch_to_addr(&instr, addr));
-	check(instr == 0x48000000);
+	check(instr == PPC_INST(0x48000000));
 }
 
 static void __init test_create_function_call(void)
@@ -499,28 +499,28 @@ static void __init test_branch_bform(void)
 	addr = (unsigned long)iptr;
 
 	/* The simplest case, branch to self, no flags */
-	check(instr_is_branch_bform(0x40000000));
+	check(instr_is_branch_bform(PPC_INST(0x40000000)));
 	/* All bits of target set, and flags */
-	check(instr_is_branch_bform(0x43ffffff));
+	check(instr_is_branch_bform(PPC_INST(0x43ffffff)));
 	/* High bit of opcode set, which is wrong */
-	check(!instr_is_branch_bform(0xc3ffffff));
+	check(!instr_is_branch_bform(PPC_INST(0xc3ffffff)));
 	/* Middle bits of opcode set, which is wrong */
-	check(!instr_is_branch_bform(0x7bffffff));
+	check(!instr_is_branch_bform(PPC_INST(0x7bffffff)));
 
 	/* Absolute conditional branch to 0x100 */
-	instr = 0x43ff0103;
+	instr = PPC_INST(0x43ff0103);
 	check(instr_is_branch_to_addr(&instr, 0x100));
 	/* Absolute conditional branch to 0x20fc */
-	instr = 0x43ff20ff;
+	instr = PPC_INST(0x43ff20ff);
 	check(instr_is_branch_to_addr(&instr, 0x20fc));
 	/* Maximum positive relative conditional branch, + 32 KB - 4B */
-	instr = 0x43ff7ffc;
+	instr = PPC_INST(0x43ff7ffc);
 	check(instr_is_branch_to_addr(&instr, addr + 0x7FFC));
 	/* Smallest negative relative conditional branch, - 4B */
-	instr = 0x43fffffc;
+	instr = PPC_INST(0x43fffffc);
 	check(instr_is_branch_to_addr(&instr, addr - 4));
 	/* Largest negative relative conditional branch, - 32 KB */
-	instr = 0x43ff8000;
+	instr = PPC_INST(0x43ff8000);
 	check(instr_is_branch_to_addr(&instr, addr - 0x8000));
 
 	/* All condition code bits set & link */
@@ -588,7 +588,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == 0x4a000000);
+	check(*q == PPC_INST(0x4a000000));
 
 	/* Maximum positive case, move x to x - 32 MB + 4 */
 	p = buf + 0x2000000;
@@ -598,7 +598,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == 0x49fffffc);
+	check(*q == PPC_INST(0x49fffffc));
 
 	/* Jump to x + 16 MB moved to x + 20 MB */
 	p = buf;
@@ -638,7 +638,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == 0x43ff8000);
+	check(*q == PPC_INST(0x43ff8000));
 
 	/* Maximum positive case, move x to x - 32 KB + 4 */
 	p = buf + 0x8000;
@@ -648,7 +648,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == 0x43ff7ffc);
+	check(*q == PPC_INST(0x43ff7ffc));
 
 	/* Jump to x + 12 KB moved to x + 20 KB */
 	p = buf;
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 4ba634b89ce5..a5f3d98862e9 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -21,6 +21,7 @@
 #include <asm/setup.h>
 #include <asm/security_features.h>
 #include <asm/firmware.h>
+#include <asm/inst.h>
 
 struct fixup_entry {
 	unsigned long	mask;
@@ -88,7 +89,7 @@ static int patch_feature_section(unsigned long value, struct fixup_entry *fcur)
 	}
 
 	for (; dest < end; dest++)
-		raw_patch_instruction(dest, PPC_INST_NOP);
+		raw_patch_instruction(dest, PPC_INST(PPC_INST_NOP));
 
 	return 0;
 }
@@ -145,15 +146,15 @@ static void do_stf_entry_barrier_fixups(enum stf_barrier_type types)
 
 		pr_devel("patching dest %lx\n", (unsigned long)dest);
 
-		patch_instruction(dest, instrs[0]);
+		patch_instruction(dest, PPC_INST(instrs[0]));
 
 		if (types & STF_BARRIER_FALLBACK)
 			patch_branch(dest + 1, (unsigned long)&stf_barrier_fallback,
 				     BRANCH_SET_LINK);
 		else
-			patch_instruction(dest + 1, instrs[1]);
+			patch_instruction(dest + 1, PPC_INST(instrs[1]));
 
-		patch_instruction(dest + 2, instrs[2]);
+		patch_instruction(dest + 2, PPC_INST(instrs[2]));
 	}
 
 	printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i,
@@ -206,12 +207,12 @@ static void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
 
 		pr_devel("patching dest %lx\n", (unsigned long)dest);
 
-		patch_instruction(dest, instrs[0]);
-		patch_instruction(dest + 1, instrs[1]);
-		patch_instruction(dest + 2, instrs[2]);
-		patch_instruction(dest + 3, instrs[3]);
-		patch_instruction(dest + 4, instrs[4]);
-		patch_instruction(dest + 5, instrs[5]);
+		patch_instruction(dest, PPC_INST(instrs[0]));
+		patch_instruction(dest + 1, PPC_INST(instrs[1]));
+		patch_instruction(dest + 2, PPC_INST(instrs[2]));
+		patch_instruction(dest + 3, PPC_INST(instrs[3]));
+		patch_instruction(dest + 4, PPC_INST(instrs[4]));
+		patch_instruction(dest + 5, PPC_INST(instrs[5]));
 	}
 	printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i,
 		(types == STF_BARRIER_NONE)                  ? "no" :
@@ -259,9 +260,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
 
 		pr_devel("patching dest %lx\n", (unsigned long)dest);
 
-		patch_instruction(dest, instrs[0]);
-		patch_instruction(dest + 1, instrs[1]);
-		patch_instruction(dest + 2, instrs[2]);
+		patch_instruction(dest, PPC_INST(instrs[0]));
+		patch_instruction(dest + 1, PPC_INST(instrs[1]));
+		patch_instruction(dest + 2, PPC_INST(instrs[2]));
 	}
 
 	printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
@@ -294,7 +295,7 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_
 		dest = (void *)start + *start;
 
 		pr_devel("patching dest %lx\n", (unsigned long)dest);
-		patch_instruction(dest, instr);
+		patch_instruction(dest, PPC_INST(instr));
 	}
 
 	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
@@ -337,8 +338,8 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_
 		dest = (void *)start + *start;
 
 		pr_devel("patching dest %lx\n", (unsigned long)dest);
-		patch_instruction(dest, instr[0]);
-		patch_instruction(dest + 1, instr[1]);
+		patch_instruction(dest, PPC_INST(instr[0]));
+		patch_instruction(dest + 1, PPC_INST(instr[1]));
 	}
 
 	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
@@ -352,7 +353,7 @@ static void patch_btb_flush_section(long *curr)
 	end = (void *)curr + *(curr + 1);
 	for (; start < end; start++) {
 		pr_devel("patching dest %lx\n", (unsigned long)start);
-		patch_instruction(start, PPC_INST_NOP);
+		patch_instruction(start, PPC_INST(PPC_INST_NOP));
 	}
 }
 
@@ -381,7 +382,7 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
 
 	for (; start < end; start++) {
 		dest = (void *)start + *start;
-		raw_patch_instruction(dest, PPC_INST_LWSYNC);
+		raw_patch_instruction(dest, PPC_INST(PPC_INST_LWSYNC));
 	}
 }
 
@@ -399,7 +400,7 @@ static void do_final_fixups(void)
 	length = (__end_interrupts - _stext) / sizeof(int);
 
 	while (length--) {
-		raw_patch_instruction(dest, *src);
+		raw_patch_instruction(dest, PPC_INST(*src));
 		src++;
 		dest++;
 	}
diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c
index 158efc8a0f53..227ebae9ba5a 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -11,6 +11,7 @@
 #include <asm/sstep.h>
 #include <asm/ppc-opcode.h>
 #include <asm/code-patching.h>
+#include <asm/inst.h>
 
 #define IMM_L(i)		((uintptr_t)(i) & 0xffff)
 
@@ -18,40 +19,40 @@
  * Defined with TEST_ prefix so it does not conflict with other
  * definitions.
  */
-#define TEST_LD(r, base, i)	(PPC_INST_LD | ___PPC_RT(r) |		\
+#define TEST_LD(r, base, i)	PPC_INST(PPC_INST_LD | ___PPC_RT(r) |		\
 					___PPC_RA(base) | IMM_L(i))
-#define TEST_LWZ(r, base, i)	(PPC_INST_LWZ | ___PPC_RT(r) |		\
+#define TEST_LWZ(r, base, i)	PPC_INST(PPC_INST_LWZ | ___PPC_RT(r) |		\
 					___PPC_RA(base) | IMM_L(i))
-#define TEST_LWZX(t, a, b)	(PPC_INST_LWZX | ___PPC_RT(t) |		\
+#define TEST_LWZX(t, a, b)	PPC_INST(PPC_INST_LWZX | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STD(r, base, i)	(PPC_INST_STD | ___PPC_RS(r) |		\
+#define TEST_STD(r, base, i)	PPC_INST(PPC_INST_STD | ___PPC_RS(r) |		\
 					___PPC_RA(base) | ((i) & 0xfffc))
-#define TEST_LDARX(t, a, b, eh)	(PPC_INST_LDARX | ___PPC_RT(t) |	\
+#define TEST_LDARX(t, a, b, eh)	PPC_INST(PPC_INST_LDARX | ___PPC_RT(t) |	\
 					___PPC_RA(a) | ___PPC_RB(b) |	\
 					__PPC_EH(eh))
-#define TEST_STDCX(s, a, b)	(PPC_INST_STDCX | ___PPC_RS(s) |	\
+#define TEST_STDCX(s, a, b)	PPC_INST(PPC_INST_STDCX | ___PPC_RS(s) |	\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LFSX(t, a, b)	(PPC_INST_LFSX | ___PPC_RT(t) |		\
+#define TEST_LFSX(t, a, b)	PPC_INST(PPC_INST_LFSX | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STFSX(s, a, b)	(PPC_INST_STFSX | ___PPC_RS(s) |	\
+#define TEST_STFSX(s, a, b)	PPC_INST(PPC_INST_STFSX | ___PPC_RS(s) |	\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LFDX(t, a, b)	(PPC_INST_LFDX | ___PPC_RT(t) |		\
+#define TEST_LFDX(t, a, b)	PPC_INST(PPC_INST_LFDX | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STFDX(s, a, b)	(PPC_INST_STFDX | ___PPC_RS(s) |	\
+#define TEST_STFDX(s, a, b)	PPC_INST(PPC_INST_STFDX | ___PPC_RS(s) |	\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LVX(t, a, b)	(PPC_INST_LVX | ___PPC_RT(t) |		\
+#define TEST_LVX(t, a, b)	PPC_INST(PPC_INST_LVX | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_STVX(s, a, b)	(PPC_INST_STVX | ___PPC_RS(s) |		\
+#define TEST_STVX(s, a, b)	PPC_INST(PPC_INST_STVX | ___PPC_RS(s) |		\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_LXVD2X(s, a, b)	(PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
-#define TEST_STXVD2X(s, a, b)	(PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
-#define TEST_ADD(t, a, b)	(PPC_INST_ADD | ___PPC_RT(t) |		\
+#define TEST_LXVD2X(s, a, b)	PPC_INST(PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
+#define TEST_STXVD2X(s, a, b)	PPC_INST(PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
+#define TEST_ADD(t, a, b)	PPC_INST(PPC_INST_ADD | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_ADD_DOT(t, a, b)	(PPC_INST_ADD | ___PPC_RT(t) |		\
+#define TEST_ADD_DOT(t, a, b)	PPC_INST(PPC_INST_ADD | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b) | 0x1)
-#define TEST_ADDC(t, a, b)	(PPC_INST_ADDC | ___PPC_RT(t) |		\
+#define TEST_ADDC(t, a, b)	PPC_INST(PPC_INST_ADDC | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b))
-#define TEST_ADDC_DOT(t, a, b)	(PPC_INST_ADDC | ___PPC_RT(t) |		\
+#define TEST_ADDC_DOT(t, a, b)	PPC_INST(PPC_INST_ADDC | ___PPC_RT(t) |		\
 					___PPC_RA(a) | ___PPC_RB(b) | 0x1)
 
 #define MAX_SUBTESTS	16
@@ -471,7 +472,7 @@ static struct compute_test compute_tests[] = {
 		.subtests = {
 			{
 				.descr = "R0 = LONG_MAX",
-				.instr = PPC_INST_NOP,
+				.instr = PPC_INST(PPC_INST_NOP),
 				.regs = {
 					.gpr[0] = LONG_MAX,
 				}
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index a0bc442f9557..f8a7a55e6ab2 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -54,6 +54,7 @@
 #include <asm/firmware.h>
 #include <asm/code-patching.h>
 #include <asm/sections.h>
+#include <asm/inst.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
@@ -880,7 +881,7 @@ static struct bpt *new_breakpoint(unsigned long a)
 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
 			bp->address = a;
 			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
-			patch_instruction(bp->instr + 1, bpinstr);
+			patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
 			return bp;
 		}
 	}
@@ -915,7 +916,7 @@ static void insert_bpts(void)
 		if (bp->enabled & BP_CIABR)
 			continue;
 		if (patch_instruction((ppc_inst *)bp->address,
-							bpinstr) != 0) {
+							PPC_INST(bpinstr)) != 0) {
 			printf("Couldn't write instruction at %lx, "
 			       "disabling breakpoint there\n", bp->address);
 			bp->enabled &= ~BP_TRAP;
@@ -950,7 +951,7 @@ static void remove_bpts(void)
 		if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
 			continue;
 		if (mread(bp->address, &instr, 4) == 4
-		    && instr == bpinstr
+		    && instr == PPC_INST(bpinstr)
 		    && patch_instruction(
 			(ppc_inst *)bp->address, bp->instr[0]) != 0)
 			printf("Couldn't remove breakpoint at %lx\n",
@@ -2846,7 +2847,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
 {
 	int nr, dotted;
 	unsigned long first_adr;
-	unsigned int inst, last_inst = 0;
+	ppc_inst inst, last_inst = PPC_INST(0);
 	unsigned char val[4];
 
 	dotted = 0;
@@ -2859,7 +2860,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
 			}
 			break;
 		}
-		inst = GETWORD(val);
+		inst = PPC_INST(GETWORD(val));
 		if (adr > first_adr && inst == last_inst) {
 			if (!dotted) {
 				printf(" ...\n");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 05/16] powerpc: Use a function for masking instructions
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (3 preceding siblings ...)
  2020-03-20  5:17 ` [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
@ 2020-03-20  5:17 ` Jordan Niethe
  2020-03-23  6:37   ` Nicholas Piggin
  2020-03-20  5:17 ` [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code Jordan Niethe
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

In preparation for using an instruction data type that can not be used
directly with the '&' operator, use a function to mask instructions.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/include/asm/sstep.h   |  6 +++---
 arch/powerpc/kernel/align.c        |  2 +-
 arch/powerpc/kernel/trace/ftrace.c |  8 ++++----
 arch/powerpc/lib/code-patching.c   | 12 ++++++------
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 9353916fcba7..ef5483288920 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -16,9 +16,9 @@ struct pt_regs;
  * Note that IS_MTMSRD returns true for both an mtmsr (32-bit)
  * and an mtmsrd (64-bit).
  */
-#define IS_MTMSRD(instr)	(((instr) & 0xfc0007be) == 0x7c000124)
-#define IS_RFID(instr)		(((instr) & 0xfc0007fe) == 0x4c000024)
-#define IS_RFI(instr)		(((instr) & 0xfc0007fe) == 0x4c000064)
+#define IS_MTMSRD(instr)	((ppc_inst_mask((instr), 0xfc0007be) == 0x7c000124))
+#define IS_RFID(instr)		((ppc_inst_mask((instr), 0xfc0007fe) == 0x4c000024))
+#define IS_RFI(instr)		((ppc_inst_mask((instr), 0xfc0007fe) == 0x4c000064))
 
 enum instruction_type {
 	COMPUTE,		/* arith/logical/CR op, etc. */
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 6008f14a145b..38542fffa179 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -331,7 +331,7 @@ int fix_alignment(struct pt_regs *regs)
 	 * when pasting to a co-processor. Furthermore, paste_last is the
 	 * synchronisation point for preceding copy/paste sequences.
 	 */
-	if ((instr & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe))
+	if (ppc_inst_mask(instr, 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe))
 		return -EIO;
 
 	r = analyse_instr(&op, regs, instr);
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 380f1ce77715..b189a34baaa2 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -98,19 +98,19 @@ static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr)
 
 static int is_bl_op(ppc_inst op)
 {
-	return (op & 0xfc000003) == 0x48000001;
+	return ppc_inst_mask(op, 0xfc000003) == 0x48000001;
 }
 
 static int is_b_op(ppc_inst op)
 {
-	return (op & 0xfc000003) == 0x48000000;
+	return ppc_inst_mask(op, 0xfc000003) == 0x48000000;
 }
 
 static unsigned long find_bl_target(unsigned long ip, ppc_inst op)
 {
 	int offset;
 
-	offset = (op & 0x03fffffc);
+	offset = ppc_inst_mask(op, 0x03fffffc);
 	/* make it signed */
 	if (offset & 0x02000000)
 		offset |= 0xfe000000;
@@ -494,7 +494,7 @@ expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
 	 * The load offset is different depending on the ABI. For simplicity
 	 * just mask it out when doing the compare.
 	 */
-	if ((op0 != 0x48000008) || ((op1 & 0xffff0000) != 0xe8410000))
+	if ((op0 != 0x48000008) || (ppc_inst_mask(op1, 0xffff0000) != 0xe8410000))
 		return 0;
 	return 1;
 }
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 5d69e836337d..e2ba23fd6f4d 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -301,7 +301,7 @@ static int instr_is_branch_bform(ppc_inst instr)
 
 int instr_is_relative_branch(ppc_inst instr)
 {
-	if (instr & BRANCH_ABSOLUTE)
+	if (ppc_inst_mask(instr, BRANCH_ABSOLUTE))
 		return 0;
 
 	return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
@@ -309,20 +309,20 @@ int instr_is_relative_branch(ppc_inst instr)
 
 int instr_is_relative_link_branch(ppc_inst instr)
 {
-	return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
+	return instr_is_relative_branch(instr) && ppc_inst_mask(instr, BRANCH_SET_LINK);
 }
 
 static unsigned long branch_iform_target(const ppc_inst *instr)
 {
 	signed long imm;
 
-	imm = *instr & 0x3FFFFFC;
+	imm = ppc_inst_mask(*instr, 0x3FFFFFC);
 
 	/* If the top bit of the immediate value is set this is negative */
 	if (imm & 0x2000000)
 		imm -= 0x4000000;
 
-	if ((*instr & BRANCH_ABSOLUTE) == 0)
+	if ((ppc_inst_mask(*instr, BRANCH_ABSOLUTE)) == 0)
 		imm += (unsigned long)instr;
 
 	return (unsigned long)imm;
@@ -332,13 +332,13 @@ static unsigned long branch_bform_target(const ppc_inst *instr)
 {
 	signed long imm;
 
-	imm = *instr & 0xFFFC;
+	imm = ppc_inst_mask(*instr, 0xFFFC);
 
 	/* If the top bit of the immediate value is set this is negative */
 	if (imm & 0x8000)
 		imm -= 0x10000;
 
-	if ((*instr & BRANCH_ABSOLUTE) == 0)
+	if ((ppc_inst_mask(*instr, BRANCH_ABSOLUTE)) == 0)
 		imm += (unsigned long)instr;
 
 	return (unsigned long)imm;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (4 preceding siblings ...)
  2020-03-20  5:17 ` [PATCH v4 05/16] powerpc: Use a function for masking instructions Jordan Niethe
@ 2020-03-20  5:17 ` Jordan Niethe
  2020-03-23  6:54   ` Balamuruhan S
  2020-03-20  5:18 ` [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality Jordan Niethe
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

In preparation for using a data type for instructions that can not be
directly used with the '>>' operator use a function for getting the op
code of an instruction.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/kernel/align.c      | 4 ++--
 arch/powerpc/lib/code-patching.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 38542fffa179..77c49dfdc1b4 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -313,8 +313,8 @@ int fix_alignment(struct pt_regs *regs)
 	}
 
 #ifdef CONFIG_SPE
-	if ((instr >> 26) == 0x4) {
-		int reg = (instr >> 21) & 0x1f;
+	if (ppc_inst_opcode(instr) == 0x4) {
+		int reg = (ppc_inst_word(instr) >> 21) & 0x1f;
 		PPC_WARN_ALIGNMENT(spe, regs);
 		return emulate_spe(regs, reg, instr);
 	}
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index e2ba23fd6f4d..04a303c059e2 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -228,7 +228,7 @@ bool is_offset_in_branch_range(long offset)
  */
 bool is_conditional_branch(ppc_inst instr)
 {
-	unsigned int opcode = instr >> 26;
+	unsigned int opcode = ppc_inst_opcode(instr);
 
 	if (opcode == 16)       /* bc, bca, bcl, bcla */
 		return true;
@@ -286,7 +286,7 @@ unsigned int create_cond_branch(const unsigned int *addr,
 
 static unsigned int branch_opcode(ppc_inst instr)
 {
-	return (instr >> 26) & 0x3F;
+	return ppc_inst_opcode(instr) & 0x3F;
 }
 
 static int instr_is_branch_iform(ppc_inst instr)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (5 preceding siblings ...)
  2020-03-20  5:17 ` [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23  6:43   ` Nicholas Piggin
  2020-03-20  5:18 ` [PATCH v4 08/16] powerpc: Use an accessor for word instructions Jordan Niethe
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

In preparation for an instruction data type that can not be directly
used with the '==' operator use functions for checking equality and
nullity.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/kernel/optprobes.c      |  2 +-
 arch/powerpc/kernel/trace/ftrace.c   | 33 +++++++++++++++-------------
 arch/powerpc/lib/code-patching.c     | 16 +++++++-------
 arch/powerpc/lib/feature-fixups.c    |  2 +-
 arch/powerpc/lib/test_emulate_step.c |  4 ++--
 arch/powerpc/xmon/xmon.c             |  4 ++--
 6 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index 1025a7a3b3a8..6027425a85f2 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -259,7 +259,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 				(unsigned long)emulate_step_addr,
 				BRANCH_SET_LINK);
 
-	if (!branch_op_callback || !branch_emulate_step)
+	if (ppc_inst_null(branch_op_callback) || ppc_inst_null(branch_emulate_step))
 		goto error;
 
 	patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index b189a34baaa2..b3645b664819 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -72,7 +72,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
 		return -EFAULT;
 
 	/* Make sure it is what we expect it to be */
-	if (replaced != old) {
+	if (!ppc_inst_equal(replaced, old)) {
 		pr_err("%p: replaced (%#x) != old (%#x)",
 		(void *)ip, replaced, old);
 		return -EINVAL;
@@ -169,7 +169,8 @@ __ftrace_make_nop(struct module *mod,
 	}
 
 	/* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
-	if (op != PPC_INST(PPC_INST_MFLR) && op != PPC_INST(PPC_INST_STD_LR)) {
+	if (!ppc_inst_equal(op, PPC_INST(PPC_INST_MFLR)) &&
+	    !ppc_inst_equal(op, PPC_INST(PPC_INST_STD_LR))) {
 		pr_err("Unexpected instruction %08x around bl _mcount\n", op);
 		return -EINVAL;
 	}
@@ -199,7 +200,7 @@ __ftrace_make_nop(struct module *mod,
 		return -EFAULT;
 	}
 
-	if (op != PPC_INST(PPC_INST_LD_TOC)) {
+	if (!ppc_inst_equal(op,  PPC_INST(PPC_INST_LD_TOC))) {
 		pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op);
 		return -EINVAL;
 	}
@@ -296,7 +297,7 @@ static unsigned long find_ftrace_tramp(unsigned long ip)
 	for (i = NUM_FTRACE_TRAMPS - 1; i >= 0; i--)
 		if (!ftrace_tramps[i])
 			continue;
-		else if (create_branch((void *)ip, ftrace_tramps[i], 0))
+		else if (!ppc_inst_null(create_branch((void *)ip, ftrace_tramps[i], 0)))
 			return ftrace_tramps[i];
 
 	return 0;
@@ -368,7 +369,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
 #else
 	ptr = ppc_global_function_entry((void *)ftrace_caller);
 #endif
-	if (!create_branch((void *)tramp, ptr, 0)) {
+	if (ppc_inst_null(create_branch((void *)tramp, ptr, 0))) {
 		pr_debug("%ps is not reachable from existing mcount tramp\n",
 				(void *)ptr);
 		return -1;
@@ -437,7 +438,7 @@ int ftrace_make_nop(struct module *mod,
 	 * then we had to use a trampoline to make the call.
 	 * Otherwise just update the call site.
 	 */
-	if (test_24bit_addr(ip, addr)) {
+	if (!ppc_inst_null(test_24bit_addr(ip, addr))) {
 		/* within range */
 		old = ftrace_call_replace(ip, addr, 1);
 		new = PPC_INST(PPC_INST_NOP);
@@ -494,7 +495,8 @@ expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
 	 * The load offset is different depending on the ABI. For simplicity
 	 * just mask it out when doing the compare.
 	 */
-	if ((op0 != 0x48000008) || (ppc_inst_mask(op1, 0xffff0000) != 0xe8410000))
+	if ((!ppc_inst_equal(op0, PPC_INST(0x48000008)) ||
+	     ((ppc_inst_mask(op1, 0xffff0000) != 0xe8410000))
 		return 0;
 	return 1;
 }
@@ -503,7 +505,7 @@ static int
 expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
 {
 	/* look for patched "NOP" on ppc64 with -mprofile-kernel */
-	if (op0 != PPC_INST(PPC_INST_NOP))
+	if (!ppc_inst_equal(op0, PPC_INST(PPC_INST_NOP)))
 		return 0;
 	return 1;
 }
@@ -559,7 +561,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	/* Ensure branch is within 24 bits */
-	if (!create_branch(ip, tramp, BRANCH_SET_LINK)) {
+	if (ppc_inst_null(create_branch(ip, tramp, BRANCH_SET_LINK))) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
@@ -584,7 +586,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 		return -EFAULT;
 
 	/* It should be pointing to a nop */
-	if (op != PPC_INST(PPC_INST_NOP)) {
+	if (!ppc_inst_equal(op,  PPC_INST(PPC_INST_NOP))) {
 		pr_err("Expected NOP but have %x\n", op);
 		return -EINVAL;
 	}
@@ -641,7 +643,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 		return -EFAULT;
 	}
 
-	if (op != PPC_INST(PPC_INST_NOP)) {
+	if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) {
 		pr_err("Unexpected call sequence at %p: %x\n", ip, op);
 		return -EINVAL;
 	}
@@ -670,7 +672,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	 * then we had to use a trampoline to make the call.
 	 * Otherwise just update the call site.
 	 */
-	if (test_24bit_addr(ip, addr)) {
+	if (!ppc_inst_null(test_24bit_addr(ip, addr))) {
 		/* within range */
 		old = PPC_INST(PPC_INST_NOP);
 		new = ftrace_call_replace(ip, addr, 1);
@@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	}
 
 	/* The new target may be within range */
-	if (test_24bit_addr(ip, addr)) {
+	if (!ppc_inst_null(test_24bit_addr(ip, addr))) {
 		/* within range */
 		if (patch_branch((ppc_inst *)ip, addr, BRANCH_SET_LINK)) {
 			pr_err("REL24 out of range!\n");
@@ -778,7 +780,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	}
 
 	/* Ensure branch is within 24 bits */
-	if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
+	if (ppc_inst_null(create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK))) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
@@ -803,7 +805,8 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	 * then we had to use a trampoline to make the call.
 	 * Otherwise just update the call site.
 	 */
-	if (test_24bit_addr(ip, addr) && test_24bit_addr(ip, old_addr)) {
+	if (!ppc_inst_null(test_24bit_addr(ip, addr)) &&
+	    !ppc_inst_null(test_24bit_addr(ip, old_addr))) {
 		/* within range */
 		old = ftrace_call_replace(ip, old_addr, 1);
 		new = ftrace_call_replace(ip, addr, 1);
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 04a303c059e2..ec3abe1a6927 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -461,20 +461,20 @@ static void __init test_branch_iform(void)
 
 	/* Out of range relative negative offset, - 32 MB + 4*/
 	instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK);
-	check(instr == 0);
+	check(ppc_inst_null(instr));
 
 	/* Out of range relative positive offset, + 32 MB */
 	instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK);
-	check(instr == 0);
+	check(ppc_inst_null(instr));
 
 	/* Unaligned target */
 	instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK);
-	check(instr == 0);
+	check(ppc_inst_null(instr));
 
 	/* Check flags are masked correctly */
 	instr = create_branch(&instr, addr, 0xFFFFFFFC);
 	check(instr_is_branch_to_addr(&instr, addr));
-	check(instr == PPC_INST(0x48000000));
+	check(ppc_inst_equal(instr, PPC_INST(0x48000000)));
 }
 
 static void __init test_create_function_call(void)
@@ -544,20 +544,20 @@ static void __init test_branch_bform(void)
 
 	/* Out of range relative negative offset, - 32 KB + 4*/
 	instr = create_cond_branch(iptr, addr - 0x8004, flags);
-	check(instr == 0);
+	check(ppc_inst_null(instr));
 
 	/* Out of range relative positive offset, + 32 KB */
 	instr = create_cond_branch(iptr, addr + 0x8000, flags);
-	check(instr == 0);
+	check(ppc_inst_null(instr));
 
 	/* Unaligned target */
 	instr = create_cond_branch(iptr, addr + 3, flags);
-	check(instr == 0);
+	check(ppc_inst_null(instr));
 
 	/* Check flags are masked correctly */
 	instr = create_cond_branch(iptr, addr, 0xFFFFFFFC);
 	check(instr_is_branch_to_addr(&instr, addr));
-	check(instr == 0x43FF0000);
+	check(ppc_inst_equal(instr, PPC_INST(0x43FF0000)));
 }
 
 static void __init test_translate_branch(void)
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index a5f3d98862e9..552106d1f64a 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
 		/* Branch within the section doesn't need translating */
 		if (target < alt_start || target > alt_end) {
 			instr = translate_branch(dest, src);
-			if (!instr)
+			if (ppc_inst_null(instr))
 				return 1;
 		}
 	}
diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c
index 227ebae9ba5a..486e057e5be1 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -846,7 +846,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs,
 {
 	struct instruction_op op;
 
-	if (!regs || !instr)
+	if (!regs || ppc_inst_null(instr))
 		return -EINVAL;
 
 	if (analyse_instr(&op, regs, instr) != 1 ||
@@ -865,7 +865,7 @@ static int __init execute_compute_instr(struct pt_regs *regs,
 	extern int exec_instr(struct pt_regs *regs);
 	extern s32 patch__exec_instr;
 
-	if (!regs || !instr)
+	if (!regs || ppc_inst_null(instr))
 		return -EINVAL;
 
 	/* Patch the NOP with the actual instruction */
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index f8a7a55e6ab2..d045e583f1c9 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -951,7 +951,7 @@ static void remove_bpts(void)
 		if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
 			continue;
 		if (mread(bp->address, &instr, 4) == 4
-		    && instr == PPC_INST(bpinstr)
+		    && ppc_inst_equal(instr, PPC_INST(bpinstr))
 		    && patch_instruction(
 			(ppc_inst *)bp->address, bp->instr[0]) != 0)
 			printf("Couldn't remove breakpoint at %lx\n",
@@ -2861,7 +2861,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
 			break;
 		}
 		inst = PPC_INST(GETWORD(val));
-		if (adr > first_adr && inst == last_inst) {
+		if (adr > first_adr && ppc_inst_equal(inst, last_inst)) {
 			if (!dotted) {
 				printf(" ...\n");
 				dotted = 1;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 08/16] powerpc: Use an accessor for word instructions
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (6 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23 11:12   ` Balamuruhan S
  2020-03-20  5:18 ` [PATCH v4 09/16] powerpc: Use a function for reading instructions Jordan Niethe
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

In preparation for prefixed instructions where all instructions are no
longer words, use an accessor for getting a word instruction as a u32
from the instruction data type.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/kernel/align.c          |   2 +-
 arch/powerpc/kernel/kprobes.c        |   2 +-
 arch/powerpc/kernel/trace/ftrace.c   |  16 +-
 arch/powerpc/lib/code-patching.c     |   2 +-
 arch/powerpc/lib/feature-fixups.c    |   4 +-
 arch/powerpc/lib/sstep.c             | 270 ++++++++++++++-------------
 arch/powerpc/lib/test_emulate_step.c |   4 +-
 arch/powerpc/xmon/xmon.c             |   4 +-
 8 files changed, 153 insertions(+), 151 deletions(-)

diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 77c49dfdc1b4..b246ca124931 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -309,7 +309,7 @@ int fix_alignment(struct pt_regs *regs)
 		/* We don't handle PPC little-endian any more... */
 		if (cpu_has_feature(CPU_FTR_PPC_LE))
 			return -EIO;
-		instr = PPC_INST(swab32(instr));
+		instr = PPC_INST(swab32(ppc_inst_word(instr)));
 	}
 
 #ifdef CONFIG_SPE
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 4c2b656615a6..0c600b6e4ead 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -242,7 +242,7 @@ static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
 		 * So, we should never get here... but, its still
 		 * good to catch them, just in case...
 		 */
-		printk("Can't step on instruction %x\n", insn);
+		printk("Can't step on instruction %x\n", ppc_inst_word(insn));
 		BUG();
 	} else {
 		/*
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index b3645b664819..7614a9f537fd 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -74,7 +74,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
 	/* Make sure it is what we expect it to be */
 	if (!ppc_inst_equal(replaced, old)) {
 		pr_err("%p: replaced (%#x) != old (%#x)",
-		(void *)ip, replaced, old);
+		(void *)ip, ppc_inst_word(replaced), ppc_inst_word(old));
 		return -EINVAL;
 	}
 
@@ -136,7 +136,7 @@ __ftrace_make_nop(struct module *mod,
 
 	/* Make sure that that this is still a 24bit jump */
 	if (!is_bl_op(op)) {
-		pr_err("Not expected bl: opcode is %x\n", op);
+		pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
 		return -EINVAL;
 	}
 
@@ -171,7 +171,7 @@ __ftrace_make_nop(struct module *mod,
 	/* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
 	if (!ppc_inst_equal(op, PPC_INST(PPC_INST_MFLR)) &&
 	    !ppc_inst_equal(op, PPC_INST(PPC_INST_STD_LR))) {
-		pr_err("Unexpected instruction %08x around bl _mcount\n", op);
+		pr_err("Unexpected instruction %08x around bl _mcount\n", ppc_inst_word(op));
 		return -EINVAL;
 	}
 #else
@@ -201,7 +201,7 @@ __ftrace_make_nop(struct module *mod,
 	}
 
 	if (!ppc_inst_equal(op,  PPC_INST(PPC_INST_LD_TOC))) {
-		pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op);
+		pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, ppc_inst_word(op));
 		return -EINVAL;
 	}
 #endif /* CONFIG_MPROFILE_KERNEL */
@@ -401,7 +401,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 
 	/* Make sure that that this is still a 24bit jump */
 	if (!is_bl_op(op)) {
-		pr_err("Not expected bl: opcode is %x\n", op);
+		pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
 		return -EINVAL;
 	}
 
@@ -525,7 +525,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 
 	if (!expected_nop_sequence(ip, op[0], op[1])) {
 		pr_err("Unexpected call sequence at %p: %x %x\n",
-		ip, op[0], op[1]);
+		ip, ppc_inst_word(op[0]), ppc_inst_word(op[1]));
 		return -EINVAL;
 	}
 
@@ -644,7 +644,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) {
-		pr_err("Unexpected call sequence at %p: %x\n", ip, op);
+		pr_err("Unexpected call sequence at %p: %x\n", ip, ppc_inst_word(op));
 		return -EINVAL;
 	}
 
@@ -723,7 +723,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 
 	/* Make sure that that this is still a 24bit jump */
 	if (!is_bl_op(op)) {
-		pr_err("Not expected bl: opcode is %x\n", op);
+		pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
 		return -EINVAL;
 	}
 
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index ec3abe1a6927..849eee63df3d 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -233,7 +233,7 @@ bool is_conditional_branch(ppc_inst instr)
 	if (opcode == 16)       /* bc, bca, bcl, bcla */
 		return true;
 	if (opcode == 19) {
-		switch ((instr >> 1) & 0x3ff) {
+		switch ((ppc_inst_word(instr) >> 1) & 0x3ff) {
 		case 16:        /* bclr, bclrl */
 		case 528:       /* bcctr, bcctrl */
 		case 560:       /* bctar, bctarl */
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 552106d1f64a..fe8ec099aa96 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -54,8 +54,8 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
 
 		/* Branch within the section doesn't need translating */
 		if (target < alt_start || target > alt_end) {
-			instr = translate_branch(dest, src);
-			if (ppc_inst_null(instr))
+			instr = ppc_inst_word(translate_branch((ppc_inst *)dest, (ppc_inst *)src));
+			if (!instr)
 				return 1;
 		}
 	}
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 1d9c766a89fe..bae878a83fa5 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1169,26 +1169,28 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	unsigned long int imm;
 	unsigned long int val, val2;
 	unsigned int mb, me, sh;
+	unsigned int word;
 	long ival;
 
+	word = ppc_inst_word(instr);
 	op->type = COMPUTE;
 
-	opcode = instr >> 26;
+	opcode = word >> 26;
 	switch (opcode) {
 	case 16:	/* bc */
 		op->type = BRANCH;
-		imm = (signed short)(instr & 0xfffc);
-		if ((instr & 2) == 0)
+		imm = (signed short)(word & 0xfffc);
+		if ((word & 2) == 0)
 			imm += regs->nip;
 		op->val = truncate_if_32bit(regs->msr, imm);
-		if (instr & 1)
+		if (word & 1)
 			op->type |= SETLK;
-		if (branch_taken(instr, regs, op))
+		if (branch_taken(word, regs, op))
 			op->type |= BRTAKEN;
 		return 1;
 #ifdef CONFIG_PPC64
 	case 17:	/* sc */
-		if ((instr & 0xfe2) == 2)
+		if ((word & 0xfe2) == 2)
 			op->type = SYSCALL;
 		else
 			op->type = UNKNOWN;
@@ -1196,21 +1198,21 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 #endif
 	case 18:	/* b */
 		op->type = BRANCH | BRTAKEN;
-		imm = instr & 0x03fffffc;
+		imm = word & 0x03fffffc;
 		if (imm & 0x02000000)
 			imm -= 0x04000000;
-		if ((instr & 2) == 0)
+		if ((word & 2) == 0)
 			imm += regs->nip;
 		op->val = truncate_if_32bit(regs->msr, imm);
-		if (instr & 1)
+		if (word & 1)
 			op->type |= SETLK;
 		return 1;
 	case 19:
-		switch ((instr >> 1) & 0x3ff) {
+		switch ((word >> 1) & 0x3ff) {
 		case 0:		/* mcrf */
 			op->type = COMPUTE + SETCC;
-			rd = 7 - ((instr >> 23) & 0x7);
-			ra = 7 - ((instr >> 18) & 0x7);
+			rd = 7 - ((word >> 23) & 0x7);
+			ra = 7 - ((word >> 18) & 0x7);
 			rd *= 4;
 			ra *= 4;
 			val = (regs->ccr >> ra) & 0xf;
@@ -1220,11 +1222,11 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		case 16:	/* bclr */
 		case 528:	/* bcctr */
 			op->type = BRANCH;
-			imm = (instr & 0x400)? regs->ctr: regs->link;
+			imm = (word & 0x400)? regs->ctr: regs->link;
 			op->val = truncate_if_32bit(regs->msr, imm);
-			if (instr & 1)
+			if (word & 1)
 				op->type |= SETLK;
-			if (branch_taken(instr, regs, op))
+			if (branch_taken(word, regs, op))
 				op->type |= BRTAKEN;
 			return 1;
 
@@ -1247,23 +1249,23 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		case 417:	/* crorc */
 		case 449:	/* cror */
 			op->type = COMPUTE + SETCC;
-			ra = (instr >> 16) & 0x1f;
-			rb = (instr >> 11) & 0x1f;
-			rd = (instr >> 21) & 0x1f;
+			ra = (word >> 16) & 0x1f;
+			rb = (word >> 11) & 0x1f;
+			rd = (word >> 21) & 0x1f;
 			ra = (regs->ccr >> (31 - ra)) & 1;
 			rb = (regs->ccr >> (31 - rb)) & 1;
-			val = (instr >> (6 + ra * 2 + rb)) & 1;
+			val = (word >> (6 + ra * 2 + rb)) & 1;
 			op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
 				(val << (31 - rd));
 			return 1;
 		}
 		break;
 	case 31:
-		switch ((instr >> 1) & 0x3ff) {
+		switch ((word >> 1) & 0x3ff) {
 		case 598:	/* sync */
 			op->type = BARRIER + BARRIER_SYNC;
 #ifdef __powerpc64__
-			switch ((instr >> 21) & 3) {
+			switch ((word >> 21) & 3) {
 			case 1:		/* lwsync */
 				op->type = BARRIER + BARRIER_LWSYNC;
 				break;
@@ -1285,20 +1287,20 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	if (!FULL_REGS(regs))
 		return -1;
 
-	rd = (instr >> 21) & 0x1f;
-	ra = (instr >> 16) & 0x1f;
-	rb = (instr >> 11) & 0x1f;
-	rc = (instr >> 6) & 0x1f;
+	rd = (word >> 21) & 0x1f;
+	ra = (word >> 16) & 0x1f;
+	rb = (word >> 11) & 0x1f;
+	rc = (word >> 6) & 0x1f;
 
 	switch (opcode) {
 #ifdef __powerpc64__
 	case 2:		/* tdi */
-		if (rd & trap_compare(regs->gpr[ra], (short) instr))
+		if (rd & trap_compare(regs->gpr[ra], (short) word))
 			goto trap;
 		return 1;
 #endif
 	case 3:		/* twi */
-		if (rd & trap_compare((int)regs->gpr[ra], (short) instr))
+		if (rd & trap_compare((int)regs->gpr[ra], (short) word))
 			goto trap;
 		return 1;
 
@@ -1307,7 +1309,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		if (!cpu_has_feature(CPU_FTR_ARCH_300))
 			return -1;
 
-		switch (instr & 0x3f) {
+		switch (word & 0x3f) {
 		case 48:	/* maddhd */
 			asm volatile(PPC_MADDHD(%0, %1, %2, %3) :
 				     "=r" (op->val) : "r" (regs->gpr[ra]),
@@ -1335,16 +1337,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 #endif
 
 	case 7:		/* mulli */
-		op->val = regs->gpr[ra] * (short) instr;
+		op->val = regs->gpr[ra] * (short) word;
 		goto compute_done;
 
 	case 8:		/* subfic */
-		imm = (short) instr;
+		imm = (short) word;
 		add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1);
 		return 1;
 
 	case 10:	/* cmpli */
-		imm = (unsigned short) instr;
+		imm = (unsigned short) word;
 		val = regs->gpr[ra];
 #ifdef __powerpc64__
 		if ((rd & 1) == 0)
@@ -1354,7 +1356,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		return 1;
 
 	case 11:	/* cmpi */
-		imm = (short) instr;
+		imm = (short) word;
 		val = regs->gpr[ra];
 #ifdef __powerpc64__
 		if ((rd & 1) == 0)
@@ -1364,35 +1366,35 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		return 1;
 
 	case 12:	/* addic */
-		imm = (short) instr;
+		imm = (short) word;
 		add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
 		return 1;
 
 	case 13:	/* addic. */
-		imm = (short) instr;
+		imm = (short) word;
 		add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
 		set_cr0(regs, op);
 		return 1;
 
 	case 14:	/* addi */
-		imm = (short) instr;
+		imm = (short) word;
 		if (ra)
 			imm += regs->gpr[ra];
 		op->val = imm;
 		goto compute_done;
 
 	case 15:	/* addis */
-		imm = ((short) instr) << 16;
+		imm = ((short) word) << 16;
 		if (ra)
 			imm += regs->gpr[ra];
 		op->val = imm;
 		goto compute_done;
 
 	case 19:
-		if (((instr >> 1) & 0x1f) == 2) {
+		if (((word >> 1) & 0x1f) == 2) {
 			/* addpcis */
-			imm = (short) (instr & 0xffc1);	/* d0 + d2 fields */
-			imm |= (instr >> 15) & 0x3e;	/* d1 field */
+			imm = (short) (word & 0xffc1);	/* d0 + d2 fields */
+			imm |= (word >> 15) & 0x3e;	/* d1 field */
 			op->val = regs->nip + (imm << 16) + 4;
 			goto compute_done;
 		}
@@ -1400,65 +1402,65 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		return 0;
 
 	case 20:	/* rlwimi */
-		mb = (instr >> 6) & 0x1f;
-		me = (instr >> 1) & 0x1f;
+		mb = (word >> 6) & 0x1f;
+		me = (word >> 1) & 0x1f;
 		val = DATA32(regs->gpr[rd]);
 		imm = MASK32(mb, me);
 		op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm);
 		goto logical_done;
 
 	case 21:	/* rlwinm */
-		mb = (instr >> 6) & 0x1f;
-		me = (instr >> 1) & 0x1f;
+		mb = (word >> 6) & 0x1f;
+		me = (word >> 1) & 0x1f;
 		val = DATA32(regs->gpr[rd]);
 		op->val = ROTATE(val, rb) & MASK32(mb, me);
 		goto logical_done;
 
 	case 23:	/* rlwnm */
-		mb = (instr >> 6) & 0x1f;
-		me = (instr >> 1) & 0x1f;
+		mb = (word >> 6) & 0x1f;
+		me = (word >> 1) & 0x1f;
 		rb = regs->gpr[rb] & 0x1f;
 		val = DATA32(regs->gpr[rd]);
 		op->val = ROTATE(val, rb) & MASK32(mb, me);
 		goto logical_done;
 
 	case 24:	/* ori */
-		op->val = regs->gpr[rd] | (unsigned short) instr;
+		op->val = regs->gpr[rd] | (unsigned short) word;
 		goto logical_done_nocc;
 
 	case 25:	/* oris */
-		imm = (unsigned short) instr;
+		imm = (unsigned short) word;
 		op->val = regs->gpr[rd] | (imm << 16);
 		goto logical_done_nocc;
 
 	case 26:	/* xori */
-		op->val = regs->gpr[rd] ^ (unsigned short) instr;
+		op->val = regs->gpr[rd] ^ (unsigned short) word;
 		goto logical_done_nocc;
 
 	case 27:	/* xoris */
-		imm = (unsigned short) instr;
+		imm = (unsigned short) word;
 		op->val = regs->gpr[rd] ^ (imm << 16);
 		goto logical_done_nocc;
 
 	case 28:	/* andi. */
-		op->val = regs->gpr[rd] & (unsigned short) instr;
+		op->val = regs->gpr[rd] & (unsigned short) word;
 		set_cr0(regs, op);
 		goto logical_done_nocc;
 
 	case 29:	/* andis. */
-		imm = (unsigned short) instr;
+		imm = (unsigned short) word;
 		op->val = regs->gpr[rd] & (imm << 16);
 		set_cr0(regs, op);
 		goto logical_done_nocc;
 
 #ifdef __powerpc64__
 	case 30:	/* rld* */
-		mb = ((instr >> 6) & 0x1f) | (instr & 0x20);
+		mb = ((word >> 6) & 0x1f) | (word & 0x20);
 		val = regs->gpr[rd];
-		if ((instr & 0x10) == 0) {
-			sh = rb | ((instr & 2) << 4);
+		if ((word & 0x10) == 0) {
+			sh = rb | ((word & 2) << 4);
 			val = ROTATE(val, sh);
-			switch ((instr >> 2) & 3) {
+			switch ((word >> 2) & 3) {
 			case 0:		/* rldicl */
 				val &= MASK64_L(mb);
 				break;
@@ -1478,7 +1480,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		} else {
 			sh = regs->gpr[rb] & 0x3f;
 			val = ROTATE(val, sh);
-			switch ((instr >> 1) & 7) {
+			switch ((word >> 1) & 7) {
 			case 0:		/* rldcl */
 				op->val = val & MASK64_L(mb);
 				goto logical_done;
@@ -1493,8 +1495,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 	case 31:
 		/* isel occupies 32 minor opcodes */
-		if (((instr >> 1) & 0x1f) == 15) {
-			mb = (instr >> 6) & 0x1f; /* bc field */
+		if (((word >> 1) & 0x1f) == 15) {
+			mb = (word >> 6) & 0x1f; /* bc field */
 			val = (regs->ccr >> (31 - mb)) & 1;
 			val2 = (ra) ? regs->gpr[ra] : 0;
 
@@ -1502,7 +1504,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			goto compute_done;
 		}
 
-		switch ((instr >> 1) & 0x3ff) {
+		switch ((word >> 1) & 0x3ff) {
 		case 4:		/* tw */
 			if (rd == 0x1f ||
 			    (rd & trap_compare((int)regs->gpr[ra],
@@ -1536,17 +1538,17 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			op->reg = rd;
 			/* only MSR_EE and MSR_RI get changed if bit 15 set */
 			/* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */
-			imm = (instr & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
+			imm = (word & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
 			op->val = imm;
 			return 0;
 #endif
 
 		case 19:	/* mfcr */
 			imm = 0xffffffffUL;
-			if ((instr >> 20) & 1) {
+			if ((word >> 20) & 1) {
 				imm = 0xf0000000UL;
 				for (sh = 0; sh < 8; ++sh) {
-					if (instr & (0x80000 >> sh))
+					if (word & (0x80000 >> sh))
 						break;
 					imm >>= 4;
 				}
@@ -1560,7 +1562,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			val = regs->gpr[rd];
 			op->ccval = regs->ccr;
 			for (sh = 0; sh < 8; ++sh) {
-				if (instr & (0x80000 >> sh))
+				if (word & (0x80000 >> sh))
 					op->ccval = (op->ccval & ~imm) |
 						(val & imm);
 				imm >>= 4;
@@ -1568,7 +1570,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			return 1;
 
 		case 339:	/* mfspr */
-			spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
+			spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
 			op->type = MFSPR;
 			op->reg = rd;
 			op->spr = spr;
@@ -1578,7 +1580,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			return 0;
 
 		case 467:	/* mtspr */
-			spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
+			spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
 			op->type = MTSPR;
 			op->val = regs->gpr[rd];
 			op->spr = spr;
@@ -1948,7 +1950,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		case 826:	/* sradi with sh_5 = 0 */
 		case 827:	/* sradi with sh_5 = 1 */
 			op->type = COMPUTE + SETREG + SETXER;
-			sh = rb | ((instr & 2) << 4);
+			sh = rb | ((word & 2) << 4);
 			ival = (signed long int) regs->gpr[rd];
 			op->val = ival >> sh;
 			op->xerval = regs->xer;
@@ -1964,7 +1966,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			if (!cpu_has_feature(CPU_FTR_ARCH_300))
 				return -1;
 			op->type = COMPUTE + SETREG;
-			sh = rb | ((instr & 2) << 4);
+			sh = rb | ((word & 2) << 4);
 			val = (signed int) regs->gpr[rd];
 			if (sh)
 				op->val = ROTATE(val, sh) & MASK64(0, 63 - sh);
@@ -1979,34 +1981,34 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
  */
 		case 54:	/* dcbst */
 			op->type = MKOP(CACHEOP, DCBST, 0);
-			op->ea = xform_ea(instr, regs);
+			op->ea = xform_ea(word, regs);
 			return 0;
 
 		case 86:	/* dcbf */
 			op->type = MKOP(CACHEOP, DCBF, 0);
-			op->ea = xform_ea(instr, regs);
+			op->ea = xform_ea(word, regs);
 			return 0;
 
 		case 246:	/* dcbtst */
 			op->type = MKOP(CACHEOP, DCBTST, 0);
-			op->ea = xform_ea(instr, regs);
+			op->ea = xform_ea(word, regs);
 			op->reg = rd;
 			return 0;
 
 		case 278:	/* dcbt */
 			op->type = MKOP(CACHEOP, DCBTST, 0);
-			op->ea = xform_ea(instr, regs);
+			op->ea = xform_ea(word, regs);
 			op->reg = rd;
 			return 0;
 
 		case 982:	/* icbi */
 			op->type = MKOP(CACHEOP, ICBI, 0);
-			op->ea = xform_ea(instr, regs);
+			op->ea = xform_ea(word, regs);
 			return 0;
 
 		case 1014:	/* dcbz */
 			op->type = MKOP(CACHEOP, DCBZ, 0);
-			op->ea = xform_ea(instr, regs);
+			op->ea = xform_ea(word, regs);
 			return 0;
 		}
 		break;
@@ -2019,14 +2021,14 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	op->update_reg = ra;
 	op->reg = rd;
 	op->val = regs->gpr[rd];
-	u = (instr >> 20) & UPDATE;
+	u = (word >> 20) & UPDATE;
 	op->vsx_flags = 0;
 
 	switch (opcode) {
 	case 31:
-		u = instr & UPDATE;
-		op->ea = xform_ea(instr, regs);
-		switch ((instr >> 1) & 0x3ff) {
+		u = word & UPDATE;
+		op->ea = xform_ea(word, regs);
+		switch ((word >> 1) & 0x3ff) {
 		case 20:	/* lwarx */
 			op->type = MKOP(LARX, 0, 4);
 			break;
@@ -2271,25 +2273,25 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 #ifdef CONFIG_VSX
 		case 12:	/* lxsiwzx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 4);
 			op->element_size = 8;
 			break;
 
 		case 76:	/* lxsiwax */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, SIGNEXT, 4);
 			op->element_size = 8;
 			break;
 
 		case 140:	/* stxsiwx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 4);
 			op->element_size = 8;
 			break;
 
 		case 268:	/* lxvx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 16);
 			op->element_size = 16;
 			op->vsx_flags = VSX_CHECK_VEC;
@@ -2298,33 +2300,33 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		case 269:	/* lxvl */
 		case 301: {	/* lxvll */
 			int nb;
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->ea = ra ? regs->gpr[ra] : 0;
 			nb = regs->gpr[rb] & 0xff;
 			if (nb > 16)
 				nb = 16;
 			op->type = MKOP(LOAD_VSX, 0, nb);
 			op->element_size = 16;
-			op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
+			op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
 				VSX_CHECK_VEC;
 			break;
 		}
 		case 332:	/* lxvdsx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 8);
 			op->element_size = 8;
 			op->vsx_flags = VSX_SPLAT;
 			break;
 
 		case 364:	/* lxvwsx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 4);
 			op->element_size = 4;
 			op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC;
 			break;
 
 		case 396:	/* stxvx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 16);
 			op->element_size = 16;
 			op->vsx_flags = VSX_CHECK_VEC;
@@ -2333,118 +2335,118 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		case 397:	/* stxvl */
 		case 429: {	/* stxvll */
 			int nb;
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->ea = ra ? regs->gpr[ra] : 0;
 			nb = regs->gpr[rb] & 0xff;
 			if (nb > 16)
 				nb = 16;
 			op->type = MKOP(STORE_VSX, 0, nb);
 			op->element_size = 16;
-			op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
+			op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
 				VSX_CHECK_VEC;
 			break;
 		}
 		case 524:	/* lxsspx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 4);
 			op->element_size = 8;
 			op->vsx_flags = VSX_FPCONV;
 			break;
 
 		case 588:	/* lxsdx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 8);
 			op->element_size = 8;
 			break;
 
 		case 652:	/* stxsspx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 4);
 			op->element_size = 8;
 			op->vsx_flags = VSX_FPCONV;
 			break;
 
 		case 716:	/* stxsdx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 8);
 			op->element_size = 8;
 			break;
 
 		case 780:	/* lxvw4x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 16);
 			op->element_size = 4;
 			break;
 
 		case 781:	/* lxsibzx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 1);
 			op->element_size = 8;
 			op->vsx_flags = VSX_CHECK_VEC;
 			break;
 
 		case 812:	/* lxvh8x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 16);
 			op->element_size = 2;
 			op->vsx_flags = VSX_CHECK_VEC;
 			break;
 
 		case 813:	/* lxsihzx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 2);
 			op->element_size = 8;
 			op->vsx_flags = VSX_CHECK_VEC;
 			break;
 
 		case 844:	/* lxvd2x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 16);
 			op->element_size = 8;
 			break;
 
 		case 876:	/* lxvb16x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(LOAD_VSX, 0, 16);
 			op->element_size = 1;
 			op->vsx_flags = VSX_CHECK_VEC;
 			break;
 
 		case 908:	/* stxvw4x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 16);
 			op->element_size = 4;
 			break;
 
 		case 909:	/* stxsibx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 1);
 			op->element_size = 8;
 			op->vsx_flags = VSX_CHECK_VEC;
 			break;
 
 		case 940:	/* stxvh8x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 16);
 			op->element_size = 2;
 			op->vsx_flags = VSX_CHECK_VEC;
 			break;
 
 		case 941:	/* stxsihx */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 2);
 			op->element_size = 8;
 			op->vsx_flags = VSX_CHECK_VEC;
 			break;
 
 		case 972:	/* stxvd2x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 16);
 			op->element_size = 8;
 			break;
 
 		case 1004:	/* stxvb16x */
-			op->reg = rd | ((instr & 1) << 5);
+			op->reg = rd | ((word & 1) << 5);
 			op->type = MKOP(STORE_VSX, 0, 16);
 			op->element_size = 1;
 			op->vsx_flags = VSX_CHECK_VEC;
@@ -2457,80 +2459,80 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	case 32:	/* lwz */
 	case 33:	/* lwzu */
 		op->type = MKOP(LOAD, u, 4);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 34:	/* lbz */
 	case 35:	/* lbzu */
 		op->type = MKOP(LOAD, u, 1);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 36:	/* stw */
 	case 37:	/* stwu */
 		op->type = MKOP(STORE, u, 4);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 38:	/* stb */
 	case 39:	/* stbu */
 		op->type = MKOP(STORE, u, 1);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 40:	/* lhz */
 	case 41:	/* lhzu */
 		op->type = MKOP(LOAD, u, 2);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 42:	/* lha */
 	case 43:	/* lhau */
 		op->type = MKOP(LOAD, SIGNEXT | u, 2);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 44:	/* sth */
 	case 45:	/* sthu */
 		op->type = MKOP(STORE, u, 2);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 46:	/* lmw */
 		if (ra >= rd)
 			break;		/* invalid form, ra in range to load */
 		op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd));
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 47:	/* stmw */
 		op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd));
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 #ifdef CONFIG_PPC_FPU
 	case 48:	/* lfs */
 	case 49:	/* lfsu */
 		op->type = MKOP(LOAD_FP, u | FPCONV, 4);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 50:	/* lfd */
 	case 51:	/* lfdu */
 		op->type = MKOP(LOAD_FP, u, 8);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 52:	/* stfs */
 	case 53:	/* stfsu */
 		op->type = MKOP(STORE_FP, u | FPCONV, 4);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 
 	case 54:	/* stfd */
 	case 55:	/* stfdu */
 		op->type = MKOP(STORE_FP, u, 8);
-		op->ea = dform_ea(instr, regs);
+		op->ea = dform_ea(word, regs);
 		break;
 #endif
 
@@ -2538,14 +2540,14 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	case 56:	/* lq */
 		if (!((rd & 1) || (rd == ra)))
 			op->type = MKOP(LOAD, 0, 16);
-		op->ea = dqform_ea(instr, regs);
+		op->ea = dqform_ea(word, regs);
 		break;
 #endif
 
 #ifdef CONFIG_VSX
 	case 57:	/* lfdp, lxsd, lxssp */
-		op->ea = dsform_ea(instr, regs);
-		switch (instr & 3) {
+		op->ea = dsform_ea(word, regs);
+		switch (word & 3) {
 		case 0:		/* lfdp */
 			if (rd & 1)
 				break;		/* reg must be even */
@@ -2569,8 +2571,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 #ifdef __powerpc64__
 	case 58:	/* ld[u], lwa */
-		op->ea = dsform_ea(instr, regs);
-		switch (instr & 3) {
+		op->ea = dsform_ea(word, regs);
+		switch (word & 3) {
 		case 0:		/* ld */
 			op->type = MKOP(LOAD, 0, 8);
 			break;
@@ -2586,16 +2588,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 #ifdef CONFIG_VSX
 	case 61:	/* stfdp, lxv, stxsd, stxssp, stxv */
-		switch (instr & 7) {
+		switch (word & 7) {
 		case 0:		/* stfdp with LSB of DS field = 0 */
 		case 4:		/* stfdp with LSB of DS field = 1 */
-			op->ea = dsform_ea(instr, regs);
+			op->ea = dsform_ea(word, regs);
 			op->type = MKOP(STORE_FP, 0, 16);
 			break;
 
 		case 1:		/* lxv */
-			op->ea = dqform_ea(instr, regs);
-			if (instr & 8)
+			op->ea = dqform_ea(word, regs);
+			if (word & 8)
 				op->reg = rd + 32;
 			op->type = MKOP(LOAD_VSX, 0, 16);
 			op->element_size = 16;
@@ -2604,7 +2606,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 		case 2:		/* stxsd with LSB of DS field = 0 */
 		case 6:		/* stxsd with LSB of DS field = 1 */
-			op->ea = dsform_ea(instr, regs);
+			op->ea = dsform_ea(word, regs);
 			op->reg = rd + 32;
 			op->type = MKOP(STORE_VSX, 0, 8);
 			op->element_size = 8;
@@ -2613,7 +2615,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 		case 3:		/* stxssp with LSB of DS field = 0 */
 		case 7:		/* stxssp with LSB of DS field = 1 */
-			op->ea = dsform_ea(instr, regs);
+			op->ea = dsform_ea(word, regs);
 			op->reg = rd + 32;
 			op->type = MKOP(STORE_VSX, 0, 4);
 			op->element_size = 8;
@@ -2621,8 +2623,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			break;
 
 		case 5:		/* stxv */
-			op->ea = dqform_ea(instr, regs);
-			if (instr & 8)
+			op->ea = dqform_ea(word, regs);
+			if (word & 8)
 				op->reg = rd + 32;
 			op->type = MKOP(STORE_VSX, 0, 16);
 			op->element_size = 16;
@@ -2634,8 +2636,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 #ifdef __powerpc64__
 	case 62:	/* std[u] */
-		op->ea = dsform_ea(instr, regs);
-		switch (instr & 3) {
+		op->ea = dsform_ea(word, regs);
+		switch (word & 3) {
 		case 0:		/* std */
 			op->type = MKOP(STORE, 0, 8);
 			break;
@@ -2663,7 +2665,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	return 0;
 
  logical_done:
-	if (instr & 1)
+	if (word & 1)
 		set_cr0(regs, op);
  logical_done_nocc:
 	op->reg = ra;
@@ -2671,7 +2673,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	return 1;
 
  arith_done:
-	if (instr & 1)
+	if (word & 1)
 		set_cr0(regs, op);
  compute_done:
 	op->reg = rd;
diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c
index 486e057e5be1..d6275a9b8ce6 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -851,7 +851,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs,
 
 	if (analyse_instr(&op, regs, instr) != 1 ||
 	    GETTYPE(op.type) != COMPUTE) {
-		pr_info("emulation failed, instruction = 0x%08x\n", instr);
+		pr_info("emulation failed, instruction = 0x%08x\n", ppc_inst_word(instr));
 		return -EFAULT;
 	}
 
@@ -871,7 +871,7 @@ static int __init execute_compute_instr(struct pt_regs *regs,
 	/* Patch the NOP with the actual instruction */
 	patch_instruction_site(&patch__exec_instr, instr);
 	if (exec_instr(regs)) {
-		pr_info("execution failed, instruction = 0x%08x\n", instr);
+		pr_info("execution failed, instruction = 0x%08x\n", ppc_inst_word(instr));
 		return -EFAULT;
 	}
 
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index d045e583f1c9..dec522fa8201 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2871,9 +2871,9 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
 		dotted = 0;
 		last_inst = inst;
 		if (praddr)
-			printf(REG"  %.8x", adr, inst);
+			printf(REG"  %.8x", adr, ppc_inst_word(inst));
 		printf("\t");
-		dump_func(inst, adr);
+		dump_func(ppc_inst_word(inst), adr);
 		printf("\n");
 	}
 	return adr - first_adr;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 09/16] powerpc: Use a function for reading instructions
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (7 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 08/16] powerpc: Use an accessor for word instructions Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23  8:00   ` Nicholas Piggin
  2020-03-20  5:18 ` [PATCH v4 10/16] powerpc: Make test_translate_branch() independent of instruction length Jordan Niethe
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Prefixed instructions will mean there are instructions of different
length. As a result dereferencing a pointer to an instruction will not
necessarily give the desired result. Introduce a function for reading
instructions from memory into the instruction data type.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/include/asm/uprobes.h |  4 ++--
 arch/powerpc/kernel/kprobes.c      |  8 ++++----
 arch/powerpc/kernel/mce_power.c    |  2 +-
 arch/powerpc/kernel/optprobes.c    |  6 +++---
 arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++-----------
 arch/powerpc/kernel/uprobes.c      |  2 +-
 arch/powerpc/lib/code-patching.c   | 22 ++++++++++----------
 arch/powerpc/lib/feature-fixups.c  |  6 +++---
 arch/powerpc/xmon/xmon.c           |  6 +++---
 9 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
index 2bbdf27d09b5..fff3c5fc90b5 100644
--- a/arch/powerpc/include/asm/uprobes.h
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -23,8 +23,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
 
 struct arch_uprobe {
 	union {
-		u32	insn;
-		u32	ixol;
+		u8	insn[MAX_UINSN_BYTES];
+		u8	ixol[MAX_UINSN_BYTES];
 	};
 };
 
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 0c600b6e4ead..f142d11d7b48 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -117,7 +117,7 @@ void *alloc_insn_page(void)
 int arch_prepare_kprobe(struct kprobe *p)
 {
 	int ret = 0;
-	kprobe_opcode_t insn = *p->addr;
+	ppc_inst insn = ppc_inst_read(p->addr);
 
 	if ((unsigned long)p->addr & 0x03) {
 		printk("Attempt to register kprobe at an unaligned address\n");
@@ -136,8 +136,8 @@ int arch_prepare_kprobe(struct kprobe *p)
 	}
 
 	if (!ret) {
-		patch_instruction(p->ainsn.insn, *p->addr);
-		p->opcode = *p->addr;
+		patch_instruction(p->ainsn.insn, insn);
+		p->opcode = ppc_inst_word(insn);
 	}
 
 	p->ainsn.boostable = 0;
@@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
 static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
 {
 	int ret;
-	ppc_inst insn = *p->ainsn.insn;
+	ppc_inst insn = ppc_inst_read((ppc_inst *)p->ainsn.insn);
 
 	/* regs->nip is also adjusted if emulate_step returns 1 */
 	ret = emulate_step(regs, insn);
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index e65616bb3a3e..d1fdb5105d32 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -374,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
 	pfn = addr_to_pfn(regs, regs->nip);
 	if (pfn != ULONG_MAX) {
 		instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
-		instr = *(ppc_inst *)(instr_addr);
+		instr = ppc_inst_read((ppc_inst *)instr_addr);
 		if (!analyse_instr(&op, &tmp, instr)) {
 			pfn = addr_to_pfn(regs, op.ea);
 			*addr = op.ea;
diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index 6027425a85f2..5b53c373373b 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -99,8 +99,8 @@ static unsigned long can_optimize(struct kprobe *p)
 	 * Ensure that the instruction is not a conditional branch,
 	 * and that can be emulated.
 	 */
-	if (!is_conditional_branch(*p->ainsn.insn) &&
-			analyse_instr(&op, &regs, *p->ainsn.insn) == 1) {
+	if (!is_conditional_branch(ppc_inst_read(p->ainsn.insn)) &&
+			analyse_instr(&op, &regs, ppc_inst_read(p->ainsn.insn)) == 1) {
 		emulate_update_regs(&regs, &op);
 		nip = regs.nip;
 	}
@@ -268,7 +268,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	/*
 	 * 3. load instruction to be emulated into relevant register, and
 	 */
-	patch_imm32_load_insns(*p->ainsn.insn, buff + TMPL_INSN_IDX);
+	patch_imm32_load_insns(*(unsigned int *)p->ainsn.insn, buff + TMPL_INSN_IDX);
 
 	/*
 	 * 4. branch back from trampoline
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 7614a9f537fd..ad451205f268 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -41,6 +41,12 @@
 #define	NUM_FTRACE_TRAMPS	8
 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
 
+static long
+read_inst(ppc_inst *inst, const void *src)
+{
+	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
+}
+
 static ppc_inst
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
@@ -68,7 +74,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
 	 */
 
 	/* read the text we want to modify */
-	if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
+	if (read_inst(&replaced, (void *)ip))
 		return -EFAULT;
 
 	/* Make sure it is what we expect it to be */
@@ -129,7 +135,7 @@ __ftrace_make_nop(struct module *mod,
 	ppc_inst op, pop;
 
 	/* read where this goes */
-	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
+	if (read_inst(&op, (void *)ip)) {
 		pr_err("Fetching opcode failed.\n");
 		return -EFAULT;
 	}
@@ -163,7 +169,7 @@ __ftrace_make_nop(struct module *mod,
 	/* When using -mkernel_profile there is no load to jump over */
 	pop = PPC_INST(PPC_INST_NOP);
 
-	if (probe_kernel_read(&op, (void *)(ip - 4), 4)) {
+	if (read_inst(&op, (void *)(ip - 4))) {
 		pr_err("Fetching instruction at %lx failed.\n", ip - 4);
 		return -EFAULT;
 	}
@@ -195,7 +201,7 @@ __ftrace_make_nop(struct module *mod,
 	 * Check what is in the next instruction. We can see ld r2,40(r1), but
 	 * on first pass after boot we will see mflr r0.
 	 */
-	if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) {
+	if (read_inst(&op, (void *)(ip+4))) {
 		pr_err("Fetching op failed.\n");
 		return -EFAULT;
 	}
@@ -344,7 +350,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
 			return -1;
 
 	/* New trampoline -- read where this goes */
-	if (probe_kernel_read(&op, (void *)tramp, sizeof(int))) {
+	if (read_inst(&op, (void *)tramp)) {
 		pr_debug("Fetching opcode failed.\n");
 		return -1;
 	}
@@ -394,7 +400,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 	ppc_inst op;
 
 	/* Read where this goes */
-	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
+	if (read_inst(&op, (void *)ip)) {
 		pr_err("Fetching opcode failed.\n");
 		return -EFAULT;
 	}
@@ -520,7 +526,10 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	struct module *mod = rec->arch.mod;
 
 	/* read where this goes */
-	if (probe_kernel_read(op, ip, sizeof(op)))
+	if (read_inst(op, ip))
+		return -EFAULT;
+
+	if (read_inst(op + 1, ip + 4))
 		return -EFAULT;
 
 	if (!expected_nop_sequence(ip, op[0], op[1])) {
@@ -582,7 +591,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	unsigned long ip = rec->ip;
 
 	/* read where this goes */
-	if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE))
+	if (read_inst(&op, (void *)ip))
 		return -EFAULT;
 
 	/* It should be pointing to a nop */
@@ -638,7 +647,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	/* Make sure we have a nop */
-	if (probe_kernel_read(&op, ip, sizeof(op))) {
+	if (read_inst(&op, ip)) {
 		pr_err("Unable to read ftrace location %p\n", ip);
 		return -EFAULT;
 	}
@@ -716,7 +725,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	}
 
 	/* read where this goes */
-	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
+	if (read_inst(&op, (void *)ip)) {
 		pr_err("Fetching opcode failed.\n");
 		return -EFAULT;
 	}
@@ -842,7 +851,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 	ppc_inst old, new;
 	int ret;
 
-	old = *(unsigned int *)&ftrace_call;
+	old = ppc_inst_read((ppc_inst *)&ftrace_call);
 	new = ftrace_call_replace(ip, (unsigned long)func, 1);
 	ret = ftrace_modify_code(ip, old, new);
 
@@ -850,7 +859,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 	/* Also update the regs callback function */
 	if (!ret) {
 		ip = (unsigned long)(&ftrace_regs_call);
-		old = *(unsigned int *)&ftrace_regs_call;
+		old = ppc_inst_read((ppc_inst *)&ftrace_regs_call);
 		new = ftrace_call_replace(ip, (unsigned long)func, 1);
 		ret = ftrace_modify_code(ip, old, new);
 	}
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index 1cfef0e5fec5..d1dff1dc3a11 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -173,7 +173,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
 	 * emulate_step() returns 1 if the insn was successfully emulated.
 	 * For all other cases, we need to single-step in hardware.
 	 */
-	ret = emulate_step(regs, auprobe->insn);
+	ret = emulate_step(regs, ppc_inst_read((ppc_inst *)auprobe->insn));
 	if (ret > 0)
 		return true;
 
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 849eee63df3d..88ee03ff55f1 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -346,9 +346,9 @@ static unsigned long branch_bform_target(const ppc_inst *instr)
 
 unsigned long branch_target(const ppc_inst *instr)
 {
-	if (instr_is_branch_iform(*instr))
+	if (instr_is_branch_iform(ppc_inst_read(instr)))
 		return branch_iform_target(instr);
-	else if (instr_is_branch_bform(*instr))
+	else if (instr_is_branch_bform(ppc_inst_read(instr)))
 		return branch_bform_target(instr);
 
 	return 0;
@@ -356,7 +356,7 @@ unsigned long branch_target(const ppc_inst *instr)
 
 int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr)
 {
-	if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
+	if (instr_is_branch_iform(ppc_inst_read(instr)) || instr_is_branch_bform(ppc_inst_read(instr)))
 		return branch_target(instr) == addr;
 
 	return 0;
@@ -368,10 +368,10 @@ ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
 
 	target = branch_target(src);
 
-	if (instr_is_branch_iform(*src))
-		return create_branch(dest, target, *src);
-	else if (instr_is_branch_bform(*src))
-		return create_cond_branch(dest, target, *src);
+	if (instr_is_branch_iform(ppc_inst_read(src)))
+		return create_branch(dest, target, ppc_inst_word(ppc_inst_read(src)));
+	else if (instr_is_branch_bform(ppc_inst_read(src)))
+		return create_cond_branch(dest, target, ppc_inst_word(ppc_inst_read(src)));
 
 	return PPC_INST(0);
 }
@@ -588,7 +588,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == PPC_INST(0x4a000000));
+	check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x4a000000)));
 
 	/* Maximum positive case, move x to x - 32 MB + 4 */
 	p = buf + 0x2000000;
@@ -598,7 +598,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == PPC_INST(0x49fffffc));
+	check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x49fffffc)));
 
 	/* Jump to x + 16 MB moved to x + 20 MB */
 	p = buf;
@@ -638,7 +638,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == PPC_INST(0x43ff8000));
+	check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x43ff8000)));
 
 	/* Maximum positive case, move x to x - 32 KB + 4 */
 	p = buf + 0x8000;
@@ -648,7 +648,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(*q == PPC_INST(0x43ff7ffc));
+	check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x43ff7ffc)));
 
 	/* Jump to x + 12 KB moved to x + 20 KB */
 	p = buf;
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index fe8ec099aa96..9e322f701e32 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -49,8 +49,8 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
 
 	instr = *src;
 
-	if (instr_is_relative_branch(*src)) {
-		unsigned int *target = (unsigned int *)branch_target(src);
+	if (instr_is_relative_branch(PPC_INST(*src))) {
+		unsigned int *target = (unsigned int *)branch_target((ppc_inst *)src);
 
 		/* Branch within the section doesn't need translating */
 		if (target < alt_start || target > alt_end) {
@@ -60,7 +60,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
 		}
 	}
 
-	raw_patch_instruction(dest, instr);
+	raw_patch_instruction((ppc_inst *)dest, PPC_INST(instr));
 
 	return 0;
 }
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index dec522fa8201..ee084411f2f5 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -704,13 +704,13 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
 	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
 		bp = at_breakpoint(regs->nip);
 		if (bp != NULL) {
-			int stepped = emulate_step(regs, bp->instr[0]);
+			int stepped = emulate_step(regs, ppc_inst_read(bp->instr));
 			if (stepped == 0) {
 				regs->nip = (unsigned long) &bp->instr[0];
 				atomic_inc(&bp->ref_count);
 			} else if (stepped < 0) {
 				printf("Couldn't single-step %s instruction\n",
-				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
+				    IS_RFID(ppc_inst_read(bp->instr))? "rfid": "mtmsrd");
 			}
 		}
 	}
@@ -953,7 +953,7 @@ static void remove_bpts(void)
 		if (mread(bp->address, &instr, 4) == 4
 		    && ppc_inst_equal(instr, PPC_INST(bpinstr))
 		    && patch_instruction(
-			(ppc_inst *)bp->address, bp->instr[0]) != 0)
+			(ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0)
 			printf("Couldn't remove breakpoint at %lx\n",
 			       bp->address);
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 10/16] powerpc: Make test_translate_branch() independent of instruction length
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (8 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 09/16] powerpc: Use a function for reading instructions Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-20  5:18 ` [PATCH v4 11/16] powerpc: Enable Prefixed Instructions Jordan Niethe
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

test_translate_branch() uses two pointers to instructions within a
buffer, p and q, to test patch_branch(). The pointer arithmetic done on
them assumes a size of 4. This will not work if the instruction length
changes. Instead do the arithmetic relative to the void * to the buffer.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/lib/code-patching.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 88ee03ff55f1..fa7f32adf029 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -563,7 +563,7 @@ static void __init test_branch_bform(void)
 static void __init test_translate_branch(void)
 {
 	unsigned long addr;
-	ppc_inst *p, *q;
+	void *p, *q;
 	void *buf;
 
 	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
@@ -576,7 +576,7 @@ static void __init test_translate_branch(void)
 	addr = (unsigned long)p;
 	patch_branch(p, addr, 0);
 	check(instr_is_branch_to_addr(p, addr));
-	q = p + 1;
+	q = buf + 4;
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(q, addr));
 
@@ -626,7 +626,7 @@ static void __init test_translate_branch(void)
 	addr = (unsigned long)p;
 	patch_instruction(p, create_cond_branch(p, addr, 0));
 	check(instr_is_branch_to_addr(p, addr));
-	q = p + 1;
+	q = buf + 4;
 	patch_instruction(q, translate_branch(q, p));
 	check(instr_is_branch_to_addr(q, addr));
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 11/16] powerpc: Enable Prefixed Instructions
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (9 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 10/16] powerpc: Make test_translate_branch() independent of instruction length Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23  7:02   ` Nicholas Piggin
  2020-03-20  5:18 ` [PATCH v4 12/16] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

From: Alistair Popple <alistair@popple.id.au>

Prefix instructions have their own FSCR bit which needs to enabled via
a CPU feature. The kernel will save the FSCR for problem state but it
needs to be enabled initially.

If prefixed instructions are made unavailable by the [H]FSCR, attempting
to use them will cause a facility unavailable exception. Add "PREFIX" to
the facility_strings[].

Currently there are no prefixed instructions that are actually emulated
by emulate_instruction() within facility_unavailable_exception().
However, when caused by a prefixed instructions the SRR1 PREFIXED bit is
set. Prepare for dealing with emulated prefixed instructions by checking
for this bit.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4:
    - Squash "Check for prefixed instructions in
      facility_unavailable_exception()" here
    - Remove dt parts for now
---
 arch/powerpc/include/asm/reg.h | 3 +++
 arch/powerpc/kernel/traps.c    | 1 +
 2 files changed, 4 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 1aa46dff0957..c7758c2ccc5f 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -397,6 +397,7 @@
 #define SPRN_RWMR	0x375	/* Region-Weighting Mode Register */
 
 /* HFSCR and FSCR bit numbers are the same */
+#define FSCR_PREFIX_LG	13	/* Enable Prefix Instructions */
 #define FSCR_SCV_LG	12	/* Enable System Call Vectored */
 #define FSCR_MSGP_LG	10	/* Enable MSGP */
 #define FSCR_TAR_LG	8	/* Enable Target Address Register */
@@ -408,11 +409,13 @@
 #define FSCR_VECVSX_LG	1	/* Enable VMX/VSX  */
 #define FSCR_FP_LG	0	/* Enable Floating Point */
 #define SPRN_FSCR	0x099	/* Facility Status & Control Register */
+#define   FSCR_PREFIX	__MASK(FSCR_PREFIX_LG)
 #define   FSCR_SCV	__MASK(FSCR_SCV_LG)
 #define   FSCR_TAR	__MASK(FSCR_TAR_LG)
 #define   FSCR_EBB	__MASK(FSCR_EBB_LG)
 #define   FSCR_DSCR	__MASK(FSCR_DSCR_LG)
 #define SPRN_HFSCR	0xbe	/* HV=1 Facility Status & Control Register */
+#define   HFSCR_PREFIX	__MASK(FSCR_PREFIX_LG)
 #define   HFSCR_MSGP	__MASK(FSCR_MSGP_LG)
 #define   HFSCR_TAR	__MASK(FSCR_TAR_LG)
 #define   HFSCR_EBB	__MASK(FSCR_EBB_LG)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 82a3438300fd..a4764b039749 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1720,6 +1720,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
 		[FSCR_TAR_LG] = "TAR",
 		[FSCR_MSGP_LG] = "MSGP",
 		[FSCR_SCV_LG] = "SCV",
+		[FSCR_PREFIX_LG] = "PREFIX",
 	};
 	char *facility = "unknown";
 	u64 value;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 12/16] powerpc: Define new SRR1 bits for a future ISA version
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (10 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 11/16] powerpc: Enable Prefixed Instructions Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23  7:03   ` Nicholas Piggin
  2020-03-20  5:18 ` [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Add the BOUNDARY SRR1 bit definition for when the cause of an alignment
exception is a prefixed instruction that crosses a 64-byte boundary.
Add the PREFIXED SRR1 bit definition for exceptions caused by prefixed
instructions.

Bit 35 of SRR1 is called SRR1_ISI_N_OR_G. This name comes from it being
used to indicate that an ISI was due to the access being no-exec or
guarded. A future ISA version adds another purpose. It is also set if
there is an access in a cache-inhibited location for prefixed
instruction.  Rename from SRR1_ISI_N_OR_G to SRR1_ISI_N_G_OR_CIP.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v2: Combined all the commits concerning SRR1 bits.
---
 arch/powerpc/include/asm/reg.h      | 4 +++-
 arch/powerpc/kvm/book3s_hv_nested.c | 2 +-
 arch/powerpc/kvm/book3s_hv_rm_mmu.c | 2 +-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index c7758c2ccc5f..173f33df4fab 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -762,7 +762,7 @@
 #endif
 
 #define   SRR1_ISI_NOPT		0x40000000 /* ISI: Not found in hash */
-#define   SRR1_ISI_N_OR_G	0x10000000 /* ISI: Access is no-exec or G */
+#define   SRR1_ISI_N_G_OR_CIP	0x10000000 /* ISI: Access is no-exec or G or CI for a prefixed instruction */
 #define   SRR1_ISI_PROT		0x08000000 /* ISI: Other protection fault */
 #define   SRR1_WAKEMASK		0x00380000 /* reason for wakeup */
 #define   SRR1_WAKEMASK_P8	0x003c0000 /* reason for wakeup on POWER8 and 9 */
@@ -789,6 +789,8 @@
 #define   SRR1_PROGADDR		0x00010000 /* SRR0 contains subsequent addr */
 
 #define   SRR1_MCE_MCP		0x00080000 /* Machine check signal caused interrupt */
+#define   SRR1_BOUNDARY		0x10000000 /* Prefixed instruction crosses 64-byte boundary */
+#define   SRR1_PREFIXED		0x20000000 /* Exception caused by prefixed instruction */
 
 #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
 #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index dc97e5be76f6..6ab685227574 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -1169,7 +1169,7 @@ static int kvmhv_translate_addr_nested(struct kvm_vcpu *vcpu,
 		} else if (vcpu->arch.trap == BOOK3S_INTERRUPT_H_INST_STORAGE) {
 			/* Can we execute? */
 			if (!gpte_p->may_execute) {
-				flags |= SRR1_ISI_N_OR_G;
+				flags |= SRR1_ISI_N_G_OR_CIP;
 				goto forward_to_l1;
 			}
 		} else {
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 220305454c23..b53a9f1c1a46 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -1260,7 +1260,7 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr,
 	status &= ~DSISR_NOHPTE;	/* DSISR_NOHPTE == SRR1_ISI_NOPT */
 	if (!data) {
 		if (gr & (HPTE_R_N | HPTE_R_G))
-			return status | SRR1_ISI_N_OR_G;
+			return status | SRR1_ISI_N_G_OR_CIP;
 		if (!hpte_read_permission(pp, slb_v & key))
 			return status | SRR1_ISI_PROT;
 	} else if (status & DSISR_ISSTORE) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (11 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 12/16] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23  7:05   ` Nicholas Piggin
  2020-03-20  5:18 ` [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Alignment interrupts can be caused by prefixed instructions accessing
memory. Prefixed instructions are not permitted to cross 64-byte
boundaries. If they do the alignment interrupt is invoked with SRR1
BOUNDARY bit set.  If this occurs send a SIGBUS to the offending process
if in user mode.  If in kernel mode call bad_page_fault().

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v2: - Move __get_user_instr() and __get_user_instr_inatomic() to this
commit (previously in "powerpc sstep: Prepare to support prefixed
instructions").
    - Rename sufx to suffix
    - Use a macro for calculating instruction length
v3: Move __get_user_{instr(), instr_inatomic()} up with the other
get_user definitions and remove nested if.
v4: Just do the things for alignment_exception(). Other changes handled
elsewhere.
---
 arch/powerpc/kernel/traps.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a4764b039749..cd8b3043c268 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -583,6 +583,10 @@ static inline int check_io_access(struct pt_regs *regs)
 #define REASON_ILLEGAL		(ESR_PIL | ESR_PUO)
 #define REASON_PRIVILEGED	ESR_PPR
 #define REASON_TRAP		ESR_PTR
+#define REASON_PREFIXED		0
+#define REASON_BOUNDARY		0
+
+#define inst_length(reason)	4
 
 /* single-step stuff */
 #define single_stepping(regs)	(current->thread.debug.dbcr0 & DBCR0_IC)
@@ -597,6 +601,10 @@ static inline int check_io_access(struct pt_regs *regs)
 #define REASON_ILLEGAL		SRR1_PROGILL
 #define REASON_PRIVILEGED	SRR1_PROGPRIV
 #define REASON_TRAP		SRR1_PROGTRAP
+#define REASON_PREFIXED		SRR1_PREFIXED
+#define REASON_BOUNDARY		SRR1_BOUNDARY
+
+#define inst_length(reason)	(((reason) & REASON_PREFIXED) ? 8 : 4)
 
 #define single_stepping(regs)	((regs)->msr & MSR_SE)
 #define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
@@ -1593,11 +1601,20 @@ void alignment_exception(struct pt_regs *regs)
 {
 	enum ctx_state prev_state = exception_enter();
 	int sig, code, fixed = 0;
+	unsigned long  reason;
 
 	/* We restore the interrupt state now */
 	if (!arch_irq_disabled_regs(regs))
 		local_irq_enable();
 
+	reason = get_reason(regs);
+
+	if (reason & REASON_BOUNDARY) {
+		sig = SIGBUS;
+		code = BUS_ADRALN;
+		goto bad;
+	}
+
 	if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT))
 		goto bail;
 
@@ -1606,7 +1623,8 @@ void alignment_exception(struct pt_regs *regs)
 		fixed = fix_alignment(regs);
 
 	if (fixed == 1) {
-		regs->nip += 4;	/* skip over emulated instruction */
+		/* skip over emulated instruction */
+		regs->nip += inst_length(reason);
 		emulate_single_step(regs);
 		goto bail;
 	}
@@ -1619,6 +1637,7 @@ void alignment_exception(struct pt_regs *regs)
 		sig = SIGBUS;
 		code = BUS_ADRALN;
 	}
+bad:
 	if (user_mode(regs))
 		_exception(sig, regs, code, regs->dar);
 	else
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (12 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23  6:58   ` Nicholas Piggin
                     ` (2 more replies)
  2020-03-20  5:18 ` [PATCH v4 15/16] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
                   ` (2 subsequent siblings)
  16 siblings, 3 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

For powerpc64, redefine the ppc_inst type so both word and prefixed
instructions can be represented. On powerpc32 the type will remain the
same.  Update places which had assumed instructions to be 4 bytes long.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
---
 arch/powerpc/include/asm/code-patching.h | 10 +--
 arch/powerpc/include/asm/inst.h          | 90 ++++++++++++++++++++++++
 arch/powerpc/include/asm/kprobes.h       |  2 +-
 arch/powerpc/include/asm/sstep.h         |  4 ++
 arch/powerpc/include/asm/uaccess.h       | 22 ++++++
 arch/powerpc/include/asm/uprobes.h       |  2 +-
 arch/powerpc/kernel/align.c              |  5 +-
 arch/powerpc/kernel/hw_breakpoint.c      |  2 +-
 arch/powerpc/kernel/kprobes.c            |  7 +-
 arch/powerpc/kernel/optprobes.c          | 42 ++++++-----
 arch/powerpc/kernel/optprobes_head.S     |  3 +
 arch/powerpc/kernel/trace/ftrace.c       | 19 ++++-
 arch/powerpc/kernel/uprobes.c            |  2 +-
 arch/powerpc/lib/code-patching.c         | 22 ++++--
 arch/powerpc/lib/sstep.c                 |  4 +-
 arch/powerpc/xmon/xmon.c                 | 38 +++++++---
 16 files changed, 221 insertions(+), 53 deletions(-)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 68bd9db334bd..bd41e1558707 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -25,11 +25,11 @@
 bool is_offset_in_branch_range(long offset);
 ppc_inst create_branch(const ppc_inst *addr,
 			   unsigned long target, int flags);
-unsigned int create_cond_branch(const ppc_inst *addr,
+ppc_inst create_cond_branch(const void *addr,
 				unsigned long target, int flags);
-int patch_branch(ppc_inst *addr, unsigned long target, int flags);
-int patch_instruction(ppc_inst *addr, ppc_inst instr);
-int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
+int patch_branch(void *addr, unsigned long target, int flags);
+int patch_instruction(void *addr, ppc_inst instr);
+int raw_patch_instruction(void *addr, ppc_inst instr);
 
 static inline unsigned long patch_site_addr(s32 *site)
 {
@@ -60,7 +60,7 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
 int instr_is_relative_branch(ppc_inst instr);
 int instr_is_relative_link_branch(ppc_inst instr);
 int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
-unsigned long branch_target(const ppc_inst *instr);
+unsigned long branch_target(const void *instr);
 ppc_inst translate_branch(const ppc_inst *dest,
 			      const ppc_inst *src);
 extern bool is_conditional_branch(ppc_inst instr);
diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 7c8596ee411e..1a40b0a71128 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -6,6 +6,95 @@
  * Instruction data type for POWER
  */
 
+#ifdef __powerpc64__
+
+typedef struct ppc_inst {
+	union {
+		struct {
+			u32 word;
+			u32 pad;
+		} __packed;
+		struct {
+			u32 prefix;
+			u32 suffix;
+		} __packed;
+	};
+} ppc_inst;
+
+#define PPC_INST(x) ((ppc_inst) { .word = (x), .pad = 0 })
+#define PPC_INST_PREFIXED(x, y) ((ppc_inst) { .prefix = (x), .suffix = (y) })
+
+static inline int ppc_inst_opcode(ppc_inst x)
+{
+	return x.word >> 26;
+}
+
+static inline bool ppc_inst_prefixed(ppc_inst x) {
+	return ppc_inst_opcode(x) == 1;
+}
+
+static inline int ppc_inst_len(ppc_inst x)
+{
+	if (ppc_inst_prefixed(x))
+		return 8;
+	else
+		return 4;
+}
+
+static inline u32 ppc_inst_word(ppc_inst x)
+{
+	return x.word;
+}
+
+static inline u32 ppc_inst_prefix(ppc_inst x)
+{
+	return x.prefix;
+}
+
+static inline u32 ppc_inst_suffix(ppc_inst x)
+{
+	return x.suffix;
+}
+
+
+static inline ppc_inst ppc_inst_read(const void *ptr)
+{
+	ppc_inst inst;
+	inst.word = *(u32 *)ptr;
+	if (ppc_inst_prefixed(inst))
+		inst.suffix = *((u32 *)ptr + 1);
+	else
+		inst.pad = 0;
+	return inst;
+}
+
+static inline void ppc_inst_write(ppc_inst *ptr, ppc_inst x)
+{
+	if (ppc_inst_prefixed(x)) {
+		*(u32 *)ptr = x.prefix;
+		*((u32 *)ptr + 1) = x.suffix;
+	} else {
+		*(u32 *)ptr = x.word;
+	}
+}
+
+static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
+{
+	return !memcmp(&x, &y, sizeof(struct ppc_inst));
+}
+
+static inline bool ppc_inst_null(ppc_inst x)
+{
+	return x.word == 0 && x.pad == 0;
+}
+
+static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
+{
+	return ppc_inst_word(x) & mask;
+}
+
+#else /* !__powerpc64__ */
+
 typedef u32 ppc_inst;
 
 #define PPC_INST(x) (x)
@@ -50,4 +139,5 @@ static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
 	return ppc_inst_word(x) & mask;
 }
 
+#endif /* __powerpc64__ */
 #endif /* _ASM_INST_H */
diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h
index 66b3f2983b22..4fc0e15e23a5 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -43,7 +43,7 @@ extern kprobe_opcode_t optprobe_template_ret[];
 extern kprobe_opcode_t optprobe_template_end[];
 
 /* Fixed instruction size for powerpc */
-#define MAX_INSN_SIZE		1
+#define MAX_INSN_SIZE		2
 #define MAX_OPTIMIZED_LENGTH	sizeof(kprobe_opcode_t)	/* 4 bytes */
 #define MAX_OPTINSN_SIZE	(optprobe_template_end - optprobe_template_entry)
 #define RELATIVEJUMP_SIZE	sizeof(kprobe_opcode_t)	/* 4 bytes */
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index ef5483288920..5eb825fb77cd 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -90,11 +90,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 GETLENGTH(t)   (((t) & PREFIXED) ? 8 : 4)
 
 #define MKOP(t, f, s)	((t) | (f) | SIZE(s))
 
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 2f500debae21..dee4fa1cd3ec 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -105,6 +105,28 @@ static inline int __access_ok(unsigned long addr, unsigned long size,
 #define __put_user_inatomic(x, ptr) \
 	__put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
 
+/*
+ * When reading an instruction iff it is a prefix, the suffix needs to be also
+ * loaded.
+ */
+#define __get_user_instr(x, ptr)			\
+({							\
+	long __gui_ret = 0;				\
+	__gui_ret = __get_user(x.prefix, (unsigned int __user *)ptr);		\
+	if (!__gui_ret && ppc_inst_prefixed(x))		\
+		__gui_ret = __get_user(x.suffix, (unsigned int __user *)ptr + 1);	\
+	__gui_ret;					\
+})
+
+#define __get_user_instr_inatomic(x, ptr)		\
+({							\
+	long __gui_ret = 0;				\
+	__gui_ret = __get_user_inatomic(x.prefix, (unsigned int __user *)ptr);		\
+	if (!__gui_ret && ppc_inst_prefixed(x))		\
+		__gui_ret = __get_user_inatomic(x.suffix, (unsigned int __user *)ptr + 1);	\
+	__gui_ret;					\
+})
+
 extern long __put_user_bad(void);
 
 /*
diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
index fff3c5fc90b5..7896a7125fa9 100644
--- a/arch/powerpc/include/asm/uprobes.h
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -14,7 +14,7 @@
 
 typedef ppc_opcode_t uprobe_opcode_t;
 
-#define MAX_UINSN_BYTES		4
+#define MAX_UINSN_BYTES		8
 #define UPROBE_XOL_SLOT_BYTES	(MAX_UINSN_BYTES)
 
 /* The following alias is needed for reference from arch-agnostic code */
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index b246ca124931..110eadd85c58 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -303,13 +303,14 @@ int fix_alignment(struct pt_regs *regs)
 	 */
 	CHECK_FULL_REGS(regs);
 
-	if (unlikely(__get_user(instr, (unsigned int __user *)regs->nip)))
+	if (unlikely(__get_user_instr(instr, (void __user *)regs->nip)))
 		return -EFAULT;
 	if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
 		/* We don't handle PPC little-endian any more... */
 		if (cpu_has_feature(CPU_FTR_PPC_LE))
 			return -EIO;
-		instr = PPC_INST(swab32(ppc_inst_word(instr)));
+		instr = PPC_INST_PREFIXED(swab32(ppc_inst_word(instr)),
+					  swab32(ppc_inst_suffix(instr)));
 	}
 
 #ifdef CONFIG_SPE
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index f001de471b98..212e0abfda43 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -249,7 +249,7 @@ static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
 	struct instruction_op op;
 	unsigned long addr = info->address;
 
-	if (__get_user_inatomic(instr, (unsigned int *)regs->nip))
+	if (__get_user_instr_inatomic(instr, (void __user*)regs->nip))
 		goto fail;
 
 	ret = analyse_instr(&op, regs, instr);
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index f142d11d7b48..1a5370a3c7c8 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -153,7 +153,7 @@ NOKPROBE_SYMBOL(arch_arm_kprobe);
 
 void arch_disarm_kprobe(struct kprobe *p)
 {
-	patch_instruction(p->addr, PPC_INST(p->opcode));
+	patch_instruction(p->addr, ppc_inst_read(p->ainsn.insn));
 }
 NOKPROBE_SYMBOL(arch_disarm_kprobe);
 
@@ -487,12 +487,13 @@ int kprobe_post_handler(struct pt_regs *regs)
 {
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	int len = ppc_inst_len(ppc_inst_read(cur->ainsn.insn));
 
 	if (!cur || user_mode(regs))
 		return 0;
 
 	/* 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) {
@@ -501,7 +502,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/optprobes.c b/arch/powerpc/kernel/optprobes.c
index 5b53c373373b..af6761859fba 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -158,38 +158,38 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr)
 
 /*
  * Generate instructions to load provided immediate 64-bit value
- * to register 'r3' and patch these instructions at 'addr'.
+ * to register 'reg' and patch these instructions at 'addr'.
  */
-void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
+void patch_imm64_load_insns(unsigned long val, int reg, kprobe_opcode_t *addr)
 {
-	/* lis r3,(op)@highest */
-	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(3) |
+	/* lis reg,(op)@highest */
+	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(reg) |
 			  ((val >> 48) & 0xffff)));
 	addr++;
 
-	/* ori r3,r3,(op)@higher */
-	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 32) & 0xffff)));
+	/* ori reg,reg,(op)@higher */
+	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
+			  ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
 	addr++;
 
-	/* rldicr r3,r3,32,31 */
-	patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(3) |
-			  ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)));
+	/* rldicr reg,reg,32,31 */
+	patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(reg) |
+			  ___PPC_RS(reg) | __PPC_SH64(32) | __PPC_ME64(31)));
 	addr++;
 
-	/* oris r3,r3,(op)@h */
-	patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 16) & 0xffff)));
+	/* oris reg,reg,(op)@h */
+	patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(reg) |
+			  ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
 	addr++;
 
-	/* ori r3,r3,(op)@l */
-	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | (val & 0xffff)));
+	/* ori reg,reg,(op)@l */
+	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
+			  ___PPC_RS(reg) | (val & 0xffff)));
 }
 
 int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 {
-	ppc_inst branch_op_callback, branch_emulate_step;
+	ppc_inst branch_op_callback, branch_emulate_step, temp;
 	kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
 	long b_offset;
 	unsigned long nip, size;
@@ -239,7 +239,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	 * Fixup the template with instructions to:
 	 * 1. load the address of the actual probepoint
 	 */
-	patch_imm64_load_insns((unsigned long)op, buff + TMPL_OP_IDX);
+	patch_imm64_load_insns((unsigned long)op, 3, buff + TMPL_OP_IDX);
 
 	/*
 	 * 2. branch to optimized_callback() and emulate_step()
@@ -268,7 +268,11 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	/*
 	 * 3. load instruction to be emulated into relevant register, and
 	 */
-	patch_imm32_load_insns(*(unsigned int *)p->ainsn.insn, buff + TMPL_INSN_IDX);
+	temp = ppc_inst_read(p->ainsn.insn);
+	patch_imm64_load_insns(ppc_inst_word(temp) |
+			       ((u64)ppc_inst_suffix(temp) << 32),
+			       4,
+			       buff + TMPL_INSN_IDX);
 
 	/*
 	 * 4. branch back from trampoline
diff --git a/arch/powerpc/kernel/optprobes_head.S b/arch/powerpc/kernel/optprobes_head.S
index cf383520843f..ff8ba4d3824d 100644
--- a/arch/powerpc/kernel/optprobes_head.S
+++ b/arch/powerpc/kernel/optprobes_head.S
@@ -94,6 +94,9 @@ optprobe_template_insn:
 	/* 2, Pass instruction to be emulated in r4 */
 	nop
 	nop
+	nop
+	nop
+	nop
 
 	.global optprobe_template_call_emulate
 optprobe_template_call_emulate:
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index ad451205f268..3b8655f57b4a 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -42,9 +42,24 @@
 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
 
 static long
-read_inst(ppc_inst *inst, const void *src)
+read_inst(ppc_inst *p, const void *src)
 {
-	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
+	ppc_inst inst;
+	long err;
+
+	err = probe_kernel_read((void *)&inst.prefix,
+				src, MCOUNT_INSN_SIZE);
+	if (err)
+		return err;
+
+	if (ppc_inst_prefixed(inst))
+		err = probe_kernel_read((void *)&inst.suffix,
+					src + 4, MCOUNT_INSN_SIZE);
+	if (err)
+		return err;
+
+	ppc_inst_write(p, inst);
+	return 0;
 }
 
 static ppc_inst
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index d1dff1dc3a11..3e4fbb5c1b1e 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -111,7 +111,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(ppc_inst_read(auprobe->insn));
 
 	user_disable_single_step(current);
 	return 0;
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index fa7f32adf029..3b8277a64b8f 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -24,17 +24,27 @@ static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
 {
 	int err = 0;
 
-	__put_user_asm(instr, patch_addr, err, "stw");
+	__put_user_asm(ppc_inst_word(instr), patch_addr, err, "stw");
 	if (err)
 		return err;
 
 	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
 							    "r" (exec_addr));
 
+	if (!ppc_inst_prefixed(instr))
+		return 0;
+
+	__put_user_asm(ppc_inst_suffix(instr), patch_addr + 4, err, "stw");
+	if (err)
+		return err;
+
+	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr + 4),
+							    "r" (exec_addr + 4));
+
 	return 0;
 }
 
-int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
+int raw_patch_instruction(void *addr, ppc_inst instr)
 {
 	return __patch_instruction(addr, instr, addr);
 }
@@ -184,7 +194,7 @@ static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
 
 #endif /* CONFIG_STRICT_KERNEL_RWX */
 
-int patch_instruction(unsigned int *addr, unsigned int instr)
+int patch_instruction(void *addr, ppc_inst instr)
 {
 	/* Make sure we aren't patching a freed init section */
 	if (init_mem_is_free && init_section_contains(addr, 4)) {
@@ -195,7 +205,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
 }
 NOKPROBE_SYMBOL(patch_instruction);
 
-int patch_branch(ppc_inst *addr, unsigned long target, int flags)
+int patch_branch(void *addr, unsigned long target, int flags)
 {
 	return patch_instruction(addr, create_branch(addr, target, flags));
 }
@@ -264,7 +274,7 @@ ppc_inst create_branch(const ppc_inst *addr,
 	return instruction;
 }
 
-unsigned int create_cond_branch(const unsigned int *addr,
+ppc_inst create_cond_branch(const void *addr,
 				unsigned long target, int flags)
 {
 	ppc_inst instruction;
@@ -344,7 +354,7 @@ static unsigned long branch_bform_target(const ppc_inst *instr)
 	return (unsigned long)imm;
 }
 
-unsigned long branch_target(const ppc_inst *instr)
+unsigned long branch_target(const void *instr)
 {
 	if (instr_is_branch_iform(ppc_inst_read(instr)))
 		return branch_iform_target(instr);
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index bae878a83fa5..ab4c71c43c8c 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1169,10 +1169,12 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 	unsigned long int imm;
 	unsigned long int val, val2;
 	unsigned int mb, me, sh;
-	unsigned int word;
+	unsigned int word, suffix;
 	long ival;
 
 	word = ppc_inst_word(instr);
+	suffix = ppc_inst_suffix(instr);
+
 	op->type = COMPUTE;
 
 	opcode = word >> 26;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index ee084411f2f5..c5536e1a3356 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -110,7 +110,7 @@ struct bpt {
 #define BP_DABR		4
 
 #define NBPTS	256
-#define BPT_WORDS	2
+#define BPT_WORDS	4
 static struct bpt bpts[NBPTS];
 static struct bpt dabr;
 static struct bpt *iabr;
@@ -118,12 +118,13 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
 
 #define BP_NUM(bp)	((bp) - bpts + 1)
 
-static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS];
+static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS] __aligned(64);
 
 /* Prototypes */
 static int cmds(struct pt_regs *);
 static int mread(unsigned long, void *, int);
 static int mwrite(unsigned long, void *, int);
+static int mread_instr(unsigned long, ppc_inst *);
 static int handle_fault(struct pt_regs *);
 static void byterev(unsigned char *, int);
 static void memex(void);
@@ -759,8 +760,8 @@ static int xmon_bpt(struct pt_regs *regs)
 
 	/* Are we at the trap at bp->instr[1] for some bp? */
 	bp = in_breakpoint_table(regs->nip, &offset);
-	if (bp != NULL && offset == 4) {
-		regs->nip = bp->address + 4;
+	if (bp != NULL && (offset == 4 || offset == 8)) {
+		regs->nip = bp->address + offset;
 		atomic_dec(&bp->ref_count);
 		return 1;
 	}
@@ -862,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
 	if (off >= sizeof(bpt_table))
 		return NULL;
 	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
-	if (bp_off != 0 && bp_off != 4)
+	if (bp_off != 0 && bp_off != 4 && bp_off != 8)
 		return NULL;
 	*offp = bp_off;
 	return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
@@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a)
 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
 			bp->address = a;
 			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
-			patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
 			return bp;
 		}
 	}
@@ -900,7 +900,7 @@ static void insert_bpts(void)
 	for (i = 0; i < NBPTS; ++i, ++bp) {
 		if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
 			continue;
-		if (mread(bp->address, &instr, 4) != 4) {
+		if (!mread_instr(bp->address, &instr)) {
 			printf("Couldn't read instruction at %lx, "
 			       "disabling breakpoint there\n", bp->address);
 			bp->enabled = 0;
@@ -913,9 +913,10 @@ static void insert_bpts(void)
 			continue;
 		}
 		patch_instruction(bp->instr, instr);
+		patch_instruction(bp->instr + ppc_inst_len(instr), PPC_INST(bpinstr));
 		if (bp->enabled & BP_CIABR)
 			continue;
-		if (patch_instruction((ppc_inst *)bp->address,
+		if (patch_instruction((void *)bp->address,
 							PPC_INST(bpinstr)) != 0) {
 			printf("Couldn't write instruction at %lx, "
 			       "disabling breakpoint there\n", bp->address);
@@ -950,7 +951,7 @@ static void remove_bpts(void)
 	for (i = 0; i < NBPTS; ++i, ++bp) {
 		if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
 			continue;
-		if (mread(bp->address, &instr, 4) == 4
+		if (mread_instr(bp->address, &instr)
 		    && ppc_inst_equal(instr, PPC_INST(bpinstr))
 		    && patch_instruction(
 			(ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0)
@@ -1166,7 +1167,7 @@ static int do_step(struct pt_regs *regs)
 	force_enable_xmon();
 	/* check we are in 64-bit kernel mode, translation enabled */
 	if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
-		if (mread(regs->nip, &instr, 4) == 4) {
+		if (mread_instr(regs->nip, &instr)) {
 			stepped = emulate_step(regs, instr);
 			if (stepped < 0) {
 				printf("Couldn't single-step %s instruction\n",
@@ -1333,7 +1334,7 @@ static long check_bp_loc(unsigned long addr)
 		printf("Breakpoints may only be placed at kernel addresses\n");
 		return 0;
 	}
-	if (!mread(addr, &instr, sizeof(instr))) {
+	if (!mread_instr(addr, &instr)) {
 		printf("Can't read instruction at address %lx\n", addr);
 		return 0;
 	}
@@ -2126,6 +2127,21 @@ mwrite(unsigned long adrs, void *buf, int size)
 	return n;
 }
 
+static int
+mread_instr(unsigned long adrs, ppc_inst *instr)
+{
+	if (setjmp(bus_error_jmp) == 0) {
+		catch_memory_errors = 1;
+		sync();
+		*instr = ppc_inst_read((void *)adrs);
+		sync();
+		/* wait a little while to see if we get a machine check */
+		__delay(200);
+	}
+	catch_memory_errors = 0;
+	return ppc_inst_len(*instr);
+}
+
 static int fault_type;
 static int fault_except;
 static char *fault_chars[] = { "--", "**", "##" };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 15/16] powerpc sstep: Add support for prefixed load/stores
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (13 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23  8:54   ` Balamuruhan S
  2020-03-20  5:18 ` [PATCH v4 16/16] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
  2020-03-23  6:18 ` [PATCH v4 00/16] Initial Prefixed Instruction support Nicholas Piggin
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

This adds emulation support for the following prefixed integer
load/stores:
  * Prefixed Load Byte and Zero (plbz)
  * Prefixed Load Halfword and Zero (plhz)
  * Prefixed Load Halfword Algebraic (plha)
  * Prefixed Load Word and Zero (plwz)
  * Prefixed Load Word Algebraic (plwa)
  * Prefixed Load Doubleword (pld)
  * Prefixed Store Byte (pstb)
  * Prefixed Store Halfword (psth)
  * Prefixed Store Word (pstw)
  * Prefixed Store Doubleword (pstd)
  * Prefixed Load Quadword (plq)
  * Prefixed Store Quadword (pstq)

the follow prefixed floating-point load/stores:
  * Prefixed Load Floating-Point Single (plfs)
  * Prefixed Load Floating-Point Double (plfd)
  * Prefixed Store Floating-Point Single (pstfs)
  * Prefixed Store Floating-Point Double (pstfd)

and for the following prefixed VSX load/stores:
  * Prefixed Load VSX Scalar Doubleword (plxsd)
  * Prefixed Load VSX Scalar Single-Precision (plxssp)
  * Prefixed Load VSX Vector [0|1]  (plxv, plxv0, plxv1)
  * Prefixed Store VSX Scalar Doubleword (pstxsd)
  * Prefixed Store VSX Scalar Single-Precision (pstxssp)
  * Prefixed Store VSX Vector [0|1] (pstxv, pstxv0, pstxv1)

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v2: - Combine all load/store patches
    - Fix the name of Type 01 instructions
    - Remove sign extension flag from pstd/pld
    - Rename sufx -> suffix
v3: - Move prefixed loads and stores into the switch statement
---
 arch/powerpc/lib/sstep.c | 159 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 159 insertions(+)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index ab4c71c43c8c..daef70eb8e22 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -187,6 +187,44 @@ static nokprobe_inline unsigned long xform_ea(unsigned int instr,
 	return ea;
 }
 
+/*
+ * Calculate effective address for a MLS:D-form / 8LS:D-form
+ * prefixed instruction
+ */
+static nokprobe_inline unsigned long mlsd_8lsd_ea(unsigned int instr,
+						  unsigned int suffix,
+						  const struct pt_regs *regs)
+{
+	int ra, prefix_r;
+	unsigned int  dd;
+	unsigned long ea, d0, d1, d;
+
+	prefix_r = instr & (1ul << 20);
+	ra = (suffix >> 16) & 0x1f;
+
+	d0 = instr & 0x3ffff;
+	d1 = suffix & 0xffff;
+	d = (d0 << 16) | d1;
+
+	/*
+	 * sign extend a 34 bit number
+	 */
+	dd = (unsigned int)(d >> 2);
+	ea = (signed int)dd;
+	ea = (ea << 2) | (d & 0x3);
+
+	if (!prefix_r && ra)
+		ea += regs->gpr[ra];
+	else if (!prefix_r && !ra)
+		; /* Leave ea as is */
+	else if (prefix_r && !ra)
+		ea += regs->nip;
+	else if (prefix_r && ra)
+		; /* Invalid form. Should already be checked for by caller! */
+
+	return ea;
+}
+
 /*
  * Return the largest power of 2, not greater than sizeof(unsigned long),
  * such that x is a multiple of it.
@@ -1166,6 +1204,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 		  ppc_inst instr)
 {
 	unsigned int opcode, ra, rb, rc, rd, spr, u;
+	unsigned int suffixopcode, prefixtype, prefix_r;
 	unsigned long int imm;
 	unsigned long int val, val2;
 	unsigned int mb, me, sh;
@@ -2652,6 +2691,126 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 			break;
 		}
 		break;
+	case 1: /* Prefixed instructions */
+		prefix_r = word & (1ul << 20);
+		ra = (suffix >> 16) & 0x1f;
+		op->update_reg = ra;
+		rd = (suffix >> 21) & 0x1f;
+		op->reg = rd;
+		op->val = regs->gpr[rd];
+
+		suffixopcode = suffix >> 26;
+		prefixtype = (word >> 24) & 0x3;
+		switch (prefixtype) {
+		case 0: /* Type 00  Eight-Byte Load/Store */
+			if (prefix_r && ra)
+				break;
+			op->ea = mlsd_8lsd_ea(word, suffix, regs);
+			switch (suffixopcode) {
+			case 41:	/* plwa */
+				op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 4);
+				break;
+			case 42:        /* plxsd */
+				op->reg = rd + 32;
+				op->type = MKOP(LOAD_VSX, PREFIXED, 8);
+				op->element_size = 8;
+				op->vsx_flags = VSX_CHECK_VEC;
+				break;
+			case 43:	/* plxssp */
+				op->reg = rd + 32;
+				op->type = MKOP(LOAD_VSX, PREFIXED, 4);
+				op->element_size = 8;
+				op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
+				break;
+			case 46:	/* pstxsd */
+				op->reg = rd + 32;
+				op->type = MKOP(STORE_VSX, PREFIXED, 8);
+				op->element_size = 8;
+				op->vsx_flags = VSX_CHECK_VEC;
+				break;
+			case 47:	/* pstxssp */
+				op->reg = rd + 32;
+				op->type = MKOP(STORE_VSX, PREFIXED, 4);
+				op->element_size = 8;
+				op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
+				break;
+			case 51:	/* plxv1 */
+				op->reg += 32;
+
+				/* fallthru */
+			case 50:	/* plxv0 */
+				op->type = MKOP(LOAD_VSX, PREFIXED, 16);
+				op->element_size = 16;
+				op->vsx_flags = VSX_CHECK_VEC;
+				break;
+			case 55:	/* pstxv1 */
+				op->reg = rd + 32;
+
+				/* fallthru */
+			case 54:	/* pstxv0 */
+				op->type = MKOP(STORE_VSX, PREFIXED, 16);
+				op->element_size = 16;
+				op->vsx_flags = VSX_CHECK_VEC;
+				break;
+			case 56:        /* plq */
+				op->type = MKOP(LOAD, PREFIXED, 16);
+				break;
+			case 57:	/* pld */
+				op->type = MKOP(LOAD, PREFIXED, 8);
+				break;
+			case 60:        /* stq */
+				op->type = MKOP(STORE, PREFIXED, 16);
+				break;
+			case 61:	/* pstd */
+				op->type = MKOP(STORE, PREFIXED, 8);
+				break;
+			}
+			break;
+		case 1: /* Type 01 Eight-Byte Register-to-Register */
+			break;
+		case 2: /* Type 10 Modified Load/Store */
+			if (prefix_r && ra)
+				break;
+			op->ea = mlsd_8lsd_ea(word, suffix, regs);
+			switch (suffixopcode) {
+			case 32:	/* plwz */
+				op->type = MKOP(LOAD, PREFIXED, 4);
+				break;
+			case 34:	/* plbz */
+				op->type = MKOP(LOAD, PREFIXED, 1);
+				break;
+			case 36:	/* pstw */
+				op->type = MKOP(STORE, PREFIXED, 4);
+				break;
+			case 38:	/* pstb */
+				op->type = MKOP(STORE, PREFIXED, 1);
+				break;
+			case 40:	/* plhz */
+				op->type = MKOP(LOAD, PREFIXED, 2);
+				break;
+			case 42:	/* plha */
+				op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 2);
+				break;
+			case 44:	/* psth */
+				op->type = MKOP(STORE, PREFIXED, 2);
+				break;
+			case 48:        /* plfs */
+				op->type = MKOP(LOAD_FP, PREFIXED | FPCONV, 4);
+				break;
+			case 50:        /* plfd */
+				op->type = MKOP(LOAD_FP, PREFIXED, 8);
+				break;
+			case 52:        /* pstfs */
+				op->type = MKOP(STORE_FP, PREFIXED | FPCONV, 4);
+				break;
+			case 54:        /* pstfd */
+				op->type = MKOP(STORE_FP, PREFIXED, 8);
+				break;
+			}
+			break;
+		case 3: /* Type 11 Modified Register-to-Register */
+			break;
+		}
 #endif /* __powerpc64__ */
 
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 16/16] powerpc sstep: Add support for prefixed fixed-point arithmetic
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (14 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 15/16] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
@ 2020-03-20  5:18 ` Jordan Niethe
  2020-03-23 10:05   ` Balamuruhan S
  2020-03-23  6:18 ` [PATCH v4 00/16] Initial Prefixed Instruction support Nicholas Piggin
  16 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-20  5:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

This adds emulation support for the following prefixed Fixed-Point
Arithmetic instructions:
  * Prefixed Add Immediate (paddi)

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v3: Since we moved the prefixed loads/stores into the load/store switch
statement it no longer makes sense to have paddi in there, so move it
out.
---
 arch/powerpc/lib/sstep.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index daef70eb8e22..6862fc019258 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1335,6 +1335,26 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
 
 	switch (opcode) {
 #ifdef __powerpc64__
+	case 1:
+		prefix_r = word & (1ul << 20);
+		ra = (suffix >> 16) & 0x1f;
+		rd = (suffix >> 21) & 0x1f;
+		op->reg = rd;
+		op->val = regs->gpr[rd];
+		suffixopcode = suffix >> 26;
+		prefixtype = (word >> 24) & 0x3;
+		switch (prefixtype) {
+		case 2:
+			if (prefix_r && ra)
+				return 0;
+			switch (suffixopcode) {
+			case 14:	/* paddi */
+				op->type = COMPUTE | PREFIXED;
+				op->val = mlsd_8lsd_ea(word, suffix, regs);
+				goto compute_done;
+			}
+		}
+		break;
 	case 2:		/* tdi */
 		if (rd & trap_compare(regs->gpr[ra], (short) word))
 			goto trap;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 02/16] xmon: Move out-of-line instructions to text section
  2020-03-20  5:17 ` [PATCH v4 02/16] xmon: Move out-of-line instructions to text section Jordan Niethe
@ 2020-03-23  5:59   ` Balamuruhan S
  2020-03-23  6:05   ` Balamuruhan S
  2020-03-23  6:22   ` Nicholas Piggin
  2 siblings, 0 replies; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23  5:59 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> To execute an instruction out of line after a breakpoint, the NIP is
> set
> to the address of struct bpt::instr. Here a copy of the instruction
> that
> was replaced with a breakpoint is kept, along with a trap so normal
> flow
> can be resumed after XOLing. The struct bpt's are located within the
> data section. This is problematic as the data section may be marked
> as
> no execute.
> 
> Instead of each struct bpt holding the instructions to be XOL'd, make
> a
> new array, bpt_table[], with enough space to hold instructions for
> the
> number of supported breakpoints. Place this array in the text
> section.
> Make struct bpt::instr a pointer to the instructions in bpt_table[]
> associated with that breakpoint. This association is a simple
> mapping:
> bpts[n] -> bpt_table[n * words per breakpoint].

Can it separate commits ?
	* introduce the array bpt_table[] and make struct bpt::instr a 
		pointer to the instructions in bpt_table[].
	* place the array in text section.

> Currently we only need
> the copied instruction followed by a trap, so 2 words per breakpoint.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/kernel/vmlinux.lds.S |  2 +-
>  arch/powerpc/xmon/xmon.c          | 22 +++++++++++++---------
>  2 files changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/vmlinux.lds.S
> b/arch/powerpc/kernel/vmlinux.lds.S
> index b4c89a1acebb..e90845b8c300 100644
> --- a/arch/powerpc/kernel/vmlinux.lds.S
> +++ b/arch/powerpc/kernel/vmlinux.lds.S
> @@ -86,7 +86,7 @@ SECTIONS
>  		ALIGN_FUNCTION();
>  #endif
>  		/* careful! __ftr_alt_* sections need to be close to
> .text */
> -		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup
> __ftr_alt_* .ref.text);
> +		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup
> __ftr_alt_* .ref.text .text.xmon_bpts);
>  #ifdef CONFIG_PPC64
>  		*(.tramp.ftrace.text);
>  #endif
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 02e3bd62cab4..7875d1a37770 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -97,7 +97,7 @@ static long *xmon_fault_jmp[NR_CPUS];
>  /* Breakpoint stuff */
>  struct bpt {
>  	unsigned long	address;
> -	unsigned int	instr[2];
> +	unsigned int	*instr;
>  	atomic_t	ref_count;
>  	int		enabled;
>  	unsigned long	pad;
> @@ -109,6 +109,7 @@ struct bpt {
>  #define BP_DABR		4
>  
>  #define NBPTS	256
> +#define BPT_WORDS	2
>  static struct bpt bpts[NBPTS];
>  static struct bpt dabr;
>  static struct bpt *iabr;
> @@ -116,6 +117,8 @@ static unsigned bpinstr = 0x7fe00008;	/* trap
> */
>  
>  #define BP_NUM(bp)	((bp) - bpts + 1)
>  
> +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS *
> BPT_WORDS];
> +
>  /* Prototypes */
>  static int cmds(struct pt_regs *);
>  static int mread(unsigned long, void *, int);
> @@ -852,16 +855,16 @@ static struct bpt *at_breakpoint(unsigned long
> pc)
>  static struct bpt *in_breakpoint_table(unsigned long nip, unsigned
> long *offp)
>  {
>  	unsigned long off;
> +	unsigned long bp_off;
>  
> -	off = nip - (unsigned long) bpts;
> -	if (off >= sizeof(bpts))
> +	off = nip - (unsigned long) bpt_table;
> +	if (off >= sizeof(bpt_table))
>  		return NULL;
> -	off %= sizeof(struct bpt);
> -	if (off != offsetof(struct bpt, instr[0])
> -	    && off != offsetof(struct bpt, instr[1]))
> +	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> +	if (bp_off != 0 && bp_off != 4)
>  		return NULL;
> -	*offp = off - offsetof(struct bpt, instr[0]);
> -	return (struct bpt *) (nip - off);
> +	*offp = bp_off;
> +	return bpts + ((off - bp_off) / (sizeof(unsigned int) *
> BPT_WORDS));

`(off - bp_off) / (sizeof(unsigned int) * BPT_WORDS)` seems to be the
actual breakpoint offset. Can we have something like,

#define NBPTS  256
#define BPT_WORDS      2
#define BPT_WORDS_SIZE (sizeof(unsigned int) * BPT_WORDS)
#define BPT_OFFSET(off, bp_word_off) ((off - bp_word_off) / 				BPT_WOR
DS_SIZE);
:::
:::
:::
bp_word_off = off % BPT_WORDS_SIZE;
if (bp_word_off != 0 && bp_word_off != 4)
        return NULL;
*offp = bp_word_off;
return bpts + BPT_OFFSET(off, bp_word_off);

-- Bala
>  }
 
 static struct bpt *new_breakpoint(unsigned long a)
@@ -876,7
> +879,8 @@ static struct bpt *new_breakpoint(unsigned long a)
 	for (bp
> = bpts; bp < &bpts[NBPTS]; ++bp) {
 		if (!bp->enabled &&
> atomic_read(&bp->ref_count) == 0) {
 			bp->address =
> a;
-			patch_instruction(&bp->instr[1], bpinstr);
+	
> 		bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
+	
> 		patch_instruction(bp->instr + 1, bpinstr);
 		
> 	return bp;
 		}
 	}


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 02/16] xmon: Move out-of-line instructions to text section
  2020-03-20  5:17 ` [PATCH v4 02/16] xmon: Move out-of-line instructions to text section Jordan Niethe
  2020-03-23  5:59   ` Balamuruhan S
@ 2020-03-23  6:05   ` Balamuruhan S
  2020-03-23  9:26     ` Jordan Niethe
  2020-03-23  6:22   ` Nicholas Piggin
  2 siblings, 1 reply; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23  6:05 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> To execute an instruction out of line after a breakpoint, the NIP is
> set
> to the address of struct bpt::instr. Here a copy of the instruction
> that
> was replaced with a breakpoint is kept, along with a trap so normal
> flow
> can be resumed after XOLing. The struct bpt's are located within the
> data section. This is problematic as the data section may be marked
> as
> no execute.
> 
> Instead of each struct bpt holding the instructions to be XOL'd, make
> a
> new array, bpt_table[], with enough space to hold instructions for
> the
> number of supported breakpoints. Place this array in the text
> section.
> Make struct bpt::instr a pointer to the instructions in bpt_table[]
> associated with that breakpoint. This association is a simple
> mapping:
> bpts[n] -> bpt_table[n * words per breakpoint].

Can we have it in separate commits ?
	* introduce the array bpt_table[] and make struct bpt::instr a 
		pointer to the instructions in bpt_table[].
	* place the array in text section.

> Currently we only need
> the copied instruction followed by a trap, so 2 words per breakpoint.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/kernel/vmlinux.lds.S |  2 +-
>  arch/powerpc/xmon/xmon.c          | 22 +++++++++++++---------
>  2 files changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/vmlinux.lds.S
> b/arch/powerpc/kernel/vmlinux.lds.S
> index b4c89a1acebb..e90845b8c300 100644
> --- a/arch/powerpc/kernel/vmlinux.lds.S
> +++ b/arch/powerpc/kernel/vmlinux.lds.S
> @@ -86,7 +86,7 @@ SECTIONS
>  		ALIGN_FUNCTION();
>  #endif
>  		/* careful! __ftr_alt_* sections need to be close to
> .text */
> -		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup
> __ftr_alt_* .ref.text);
> +		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup
> __ftr_alt_* .ref.text .text.xmon_bpts);
>  #ifdef CONFIG_PPC64
>  		*(.tramp.ftrace.text);
>  #endif
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 02e3bd62cab4..7875d1a37770 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -97,7 +97,7 @@ static long *xmon_fault_jmp[NR_CPUS];
>  /* Breakpoint stuff */
>  struct bpt {
>  	unsigned long	address;
> -	unsigned int	instr[2];
> +	unsigned int	*instr;
>  	atomic_t	ref_count;
>  	int		enabled;
>  	unsigned long	pad;
> @@ -109,6 +109,7 @@ struct bpt {
>  #define BP_DABR		4
>  
>  #define NBPTS	256
> +#define BPT_WORDS	2
>  static struct bpt bpts[NBPTS];
>  static struct bpt dabr;
>  static struct bpt *iabr;
> @@ -116,6 +117,8 @@ static unsigned bpinstr = 0x7fe00008;	/* trap
> */
>  
>  #define BP_NUM(bp)	((bp) - bpts + 1)
>  
> +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS *
> BPT_WORDS];
> +
>  /* Prototypes */
>  static int cmds(struct pt_regs *);
>  static int mread(unsigned long, void *, int);
> @@ -852,16 +855,16 @@ static struct bpt *at_breakpoint(unsigned long
> pc)
>  static struct bpt *in_breakpoint_table(unsigned long nip, unsigned
> long *offp)
>  {
>  	unsigned long off;
> +	unsigned long bp_off;
>  
> -	off = nip - (unsigned long) bpts;
> -	if (off >= sizeof(bpts))
> +	off = nip - (unsigned long) bpt_table;
> +	if (off >= sizeof(bpt_table))
>  		return NULL;
> -	off %= sizeof(struct bpt);
> -	if (off != offsetof(struct bpt, instr[0])
> -	    && off != offsetof(struct bpt, instr[1]))
> +	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> +	if (bp_off != 0 && bp_off != 4)
>  		return NULL;
> -	*offp = off - offsetof(struct bpt, instr[0]);
> -	return (struct bpt *) (nip - off);
> +	*offp = bp_off;
> +	return bpts + ((off - bp_off) / (sizeof(unsigned int) *
> BPT_WORDS));

`(off - bp_off) / (sizeof(unsigned int) * BPT_WORDS)` seems to be the
actual breakpoint offset. Can we have something like,

#define NBPTS  256
#define BPT_WORDS      2
#define BPT_WORDS_SIZE (sizeof(unsigned int) * BPT_WORDS)
#define BPT_OFFSET(off, bp_word_off) ((off - bp_word_off) / \					BPT_WORDS_SIZE)
;
:::
:::
:::
bp_word_off = off % BPT_WORDS_SIZE;
if (bp_word_off != 0 && bp_word_off != 4)
        return NULL;
*offp = bp_word_off;
return bpts + BPT_OFFSET(off, bp_word_off);

-- Bala


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-20  5:17 ` [PATCH v4 03/16] powerpc: Use a datatype for instructions Jordan Niethe
@ 2020-03-23  6:07   ` Balamuruhan S
  2020-03-23  6:23   ` Nicholas Piggin
  2020-04-01 10:32   ` Balamuruhan S
  2 siblings, 0 replies; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23  6:07 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> Currently unsigned ints are used to represent instructions on powerpc.
> This has worked well as instructions have always been 4 byte words.
> However, a future ISA version will introduce some changes to
> instructions that mean this scheme will no longer work as well. This
> change is Prefixed Instructions. A prefixed instruction is made up of a
> word prefix followed by a word suffix to make an 8 byte double word
> instruction. No matter the endianess of the system the prefix always
> comes first. Prefixed instructions are only planned for powerpc64.
> 
> Introduce a ppc_inst type to represent both prefixed and word
> instructions on powerpc64 while keeping it possible to exclusively have
> word instructions on powerpc32, A latter patch will expand the type to
> include prefixed instructions but for now just typedef it to a u32.
> 
> Later patches will introduce helper functions and macros for
> manipulating the instructions so that powerpc64 and powerpc32 might
> maintain separate type definitions.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>  arch/powerpc/include/asm/code-patching.h | 31 +++++------
>  arch/powerpc/include/asm/inst.h          | 53 +++++++++++++++++++
>  arch/powerpc/include/asm/sstep.h         |  5 +-
>  arch/powerpc/kernel/align.c              |  2 +-
>  arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
>  arch/powerpc/kernel/kprobes.c            |  2 +-
>  arch/powerpc/kernel/mce_power.c          |  5 +-
>  arch/powerpc/kernel/optprobes.c          | 10 ++--
>  arch/powerpc/kernel/trace/ftrace.c       | 66 ++++++++++++------------
>  arch/powerpc/kvm/emulate_loadstore.c     |  1 +
>  arch/powerpc/lib/code-patching.c         | 54 +++++++++----------
>  arch/powerpc/lib/sstep.c                 |  4 +-
>  arch/powerpc/lib/test_emulate_step.c     |  9 ++--
>  arch/powerpc/xmon/xmon.c                 | 12 ++---
>  14 files changed, 160 insertions(+), 97 deletions(-)
>  create mode 100644 arch/powerpc/include/asm/inst.h
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h
> b/arch/powerpc/include/asm/code-patching.h
> index 898b54262881..cb5106f92d67 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -11,6 +11,7 @@
>  #include <linux/string.h>
>  #include <linux/kallsyms.h>
>  #include <asm/asm-compat.h>
> +#include <asm/inst.h>
>  
>  /* Flags for create_branch:
>   * "b"   == create_branch(addr, target, 0);
> @@ -22,27 +23,27 @@
>  #define BRANCH_ABSOLUTE	0x2
>  
>  bool is_offset_in_branch_range(long offset);
> -unsigned int create_branch(const unsigned int *addr,
> +ppc_inst create_branch(const ppc_inst *addr,
>  			   unsigned long target, int flags);
> -unsigned int create_cond_branch(const unsigned int *addr,
> +unsigned int create_cond_branch(const ppc_inst *addr,
>  				unsigned long target, int flags);
> -int patch_branch(unsigned int *addr, unsigned long target, int flags);
> -int patch_instruction(unsigned int *addr, unsigned int instr);
> -int raw_patch_instruction(unsigned int *addr, unsigned int instr);
> +int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> +int patch_instruction(ppc_inst *addr, ppc_inst instr);
> +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
>  
>  static inline unsigned long patch_site_addr(s32 *site)
>  {
>  	return (unsigned long)site + *site;
>  }
>  
> -static inline int patch_instruction_site(s32 *site, unsigned int instr)
> +static inline int patch_instruction_site(s32 *site, ppc_inst instr)
>  {
> -	return patch_instruction((unsigned int *)patch_site_addr(site), instr);
> +	return patch_instruction((ppc_inst *)patch_site_addr(site), instr);
>  }
>  
>  static inline int patch_branch_site(s32 *site, unsigned long target, int
> flags)
>  {
> -	return patch_branch((unsigned int *)patch_site_addr(site), target,
> flags);
> +	return patch_branch((ppc_inst *)patch_site_addr(site), target, flags);
>  }
>  
>  static inline int modify_instruction(unsigned int *addr, unsigned int clr,
> @@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site,
> unsigned int clr, unsigned
>  	return modify_instruction((unsigned int *)patch_site_addr(site), clr,
> set);
>  }
>  
> -int instr_is_relative_branch(unsigned int instr);
> -int instr_is_relative_link_branch(unsigned int instr);
> -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
> -unsigned long branch_target(const unsigned int *instr);
> -unsigned int translate_branch(const unsigned int *dest,
> -			      const unsigned int *src);
> -extern bool is_conditional_branch(unsigned int instr);
> +int instr_is_relative_branch(ppc_inst instr);
> +int instr_is_relative_link_branch(ppc_inst instr);
> +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> +unsigned long branch_target(const ppc_inst *instr);
> +ppc_inst translate_branch(const ppc_inst *dest,
> +			      const ppc_inst *src);
> +extern bool is_conditional_branch(ppc_inst instr);
>  #ifdef CONFIG_PPC_BOOK3E_64
>  void __patch_exception(int exc, unsigned long addr);
>  #define patch_exception(exc, name) do { \
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> new file mode 100644
> index 000000000000..7c8596ee411e
> --- /dev/null
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -0,0 +1,53 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#ifndef _ASM_INST_H
> +#define _ASM_INST_H
> +
> +/*
> + * Instruction data type for POWER
> + */
> +
> +typedef u32 ppc_inst;
> +
> +#define PPC_INST(x) (x)
> +
> +static inline int ppc_inst_len(ppc_inst x)

should we consider `size_t` which is of type unsigned int ?

-- Bala
> +{
> +	return sizeof(ppc_inst);
> +}
> +
> +static inline int ppc_inst_opcode(ppc_inst x)
> +{
> +	return x >> 26;
> +}
> +
> +static inline u32 ppc_inst_word(ppc_inst x)
> +{
> +	return x;
> +}
> +
> +static inline ppc_inst ppc_inst_read(const ppc_inst *ptr)
> +{
> +	return *(ppc_inst *)ptr;
> +}
> +
> +static inline void ppc_inst_write(void *ptr, ppc_inst x)
> +{
> +	*(ppc_inst *)ptr = x;
> +}
> +
> +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
> +{
> +	return x == y;
> +}
> +
> +static inline bool ppc_inst_null(ppc_inst x)
> +{
> +	return x == 0;
> +}
> +
> +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
> +{
> +	return ppc_inst_word(x) & mask;
> +}
> +
> +#endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/include/asm/sstep.h
> b/arch/powerpc/include/asm/sstep.h
> index 769f055509c9..9353916fcba7 100644
> --- a/arch/powerpc/include/asm/sstep.h
> +++ b/arch/powerpc/include/asm/sstep.h
> @@ -2,6 +2,7 @@
>  /*
>   * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
>   */
> +#include <asm/inst.h>
>  
>  struct pt_regs;
>  
> @@ -132,7 +133,7 @@ union vsx_reg {
>   * otherwise.
>   */
>  extern int analyse_instr(struct instruction_op *op, const struct pt_regs
> *regs,
> -			 unsigned int instr);
> +			 ppc_inst instr);
>  
>  /*
>   * Emulate an instruction that can be executed just by updating
> @@ -149,7 +150,7 @@ 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, ppc_inst instr);
>  
>  /*
>   * 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..34594aaa44de 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -293,7 +293,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int
> reg,
>  
>  int fix_alignment(struct pt_regs *regs)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  	struct instruction_op op;
>  	int r, type;
>  
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> b/arch/powerpc/kernel/hw_breakpoint.c
> index 2462cd7c565c..06b97353d231 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -24,6 +24,7 @@
>  #include <asm/debug.h>
>  #include <asm/debugfs.h>
>  #include <asm/hvcall.h>
> +#include <asm/inst.h>
>  #include <linux/uaccess.h>
>  
>  /*
> @@ -243,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size, struct
> arch_hw_breakpoint *info)
>  static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
>  			     struct arch_hw_breakpoint *info)
>  {
> -	unsigned int instr = 0;
> +	ppc_inst instr = 0;
>  	int ret, type, size;
>  	struct instruction_op op;
>  	unsigned long addr = info->address;
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 337516df17d4..e7205adc9820 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
>  static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
>  {
>  	int ret;
> -	unsigned int insn = *p->ainsn.insn;
> +	ppc_inst insn = *p->ainsn.insn;
>  
>  	/* regs->nip is also adjusted if emulate_step returns 1 */
>  	ret = emulate_step(regs, insn);
> diff --git a/arch/powerpc/kernel/mce_power.c
> b/arch/powerpc/kernel/mce_power.c
> index 1cbf7f1a4e3d..e65616bb3a3e 100644
> --- a/arch/powerpc/kernel/mce_power.c
> +++ b/arch/powerpc/kernel/mce_power.c
> @@ -20,6 +20,7 @@
>  #include <asm/sstep.h>
>  #include <asm/exception-64s.h>
>  #include <asm/extable.h>
> +#include <asm/inst.h>
>  
>  /*
>   * Convert an address related to an mm to a PFN. NOTE: we are in real
> @@ -365,7 +366,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> *regs, uint64_t *addr,
>  	 * in real-mode is tricky and can lead to recursive
>  	 * faults
>  	 */
> -	int instr;
> +	ppc_inst instr;
>  	unsigned long pfn, instr_addr;
>  	struct instruction_op op;
>  	struct pt_regs tmp = *regs;
> @@ -373,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> *regs, uint64_t *addr,
>  	pfn = addr_to_pfn(regs, regs->nip);
>  	if (pfn != ULONG_MAX) {
>  		instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
> -		instr = *(unsigned int *)(instr_addr);
> +		instr = *(ppc_inst *)(instr_addr);
>  		if (!analyse_instr(&op, &tmp, instr)) {
>  			pfn = addr_to_pfn(regs, op.ea);
>  			*addr = op.ea;
> diff --git a/arch/powerpc/kernel/optprobes.c
> b/arch/powerpc/kernel/optprobes.c
> index 024f7aad1952..f5e8cce438a3 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -189,8 +189,8 @@ void patch_imm64_load_insns(unsigned long val,
> kprobe_opcode_t *addr)
>  
>  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe
> *p)
>  {
> -	kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
> -	kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
> +	ppc_inst branch_op_callback, branch_emulate_step;
> +	kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
>  	long b_offset;
>  	unsigned long nip, size;
>  	int rc, i;
> @@ -251,11 +251,11 @@ int arch_prepare_optimized_kprobe(struct
> optimized_kprobe *op, struct kprobe *p)
>  		goto error;
>  	}
>  
> -	branch_op_callback = create_branch((unsigned int *)buff +
> TMPL_CALL_HDLR_IDX,
> +	branch_op_callback = create_branch((ppc_inst *)buff +
> TMPL_CALL_HDLR_IDX,
>  				(unsigned long)op_callback_addr,
>  				BRANCH_SET_LINK);
>  
> -	branch_emulate_step = create_branch((unsigned int *)buff +
> TMPL_EMULATE_IDX,
> +	branch_emulate_step = create_branch((ppc_inst *)buff +
> TMPL_EMULATE_IDX,
>  				(unsigned long)emulate_step_addr,
>  				BRANCH_SET_LINK);
>  
> @@ -316,7 +316,7 @@ void arch_optimize_kprobes(struct list_head *oplist)
>  		memcpy(op->optinsn.copied_insn, op->kp.addr,
>  					       RELATIVEJUMP_SIZE);
>  		patch_instruction(op->kp.addr,
> -			create_branch((unsigned int *)op->kp.addr,
> +			create_branch((ppc_inst *)op->kp.addr,
>  				      (unsigned long)op->optinsn.insn, 0));
>  		list_del_init(&op->list);
>  	}
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c
> index 7ea0ca044b65..5787ccffb4df 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -27,6 +27,7 @@
>  #include <asm/code-patching.h>
>  #include <asm/ftrace.h>
>  #include <asm/syscall.h>
> +#include <asm/inst.h>
>  
>  
>  #ifdef CONFIG_DYNAMIC_FTRACE
> @@ -40,23 +41,23 @@
>  #define	NUM_FTRACE_TRAMPS	8
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
>  
> -static unsigned int
> +static ppc_inst
>  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  
>  	addr = ppc_function_entry((void *)addr);
>  
>  	/* if (link) set op to 'bl' else 'b' */
> -	op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> +	op = create_branch((ppc_inst *)ip, addr, link ? 1 : 0);
>  
>  	return op;
>  }
>  
>  static int
> -ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
> +ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
>  {
> -	unsigned int replaced;
> +	ppc_inst replaced;
>  
>  	/*
>  	 * Note:
> @@ -78,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> unsigned int new)
>  	}
>  
>  	/* replace the text with the new text */
> -	if (patch_instruction((unsigned int *)ip, new))
> +	if (patch_instruction((ppc_inst *)ip, new))
>  		return -EPERM;
>  
>  	return 0;
> @@ -87,25 +88,25 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> unsigned int new)
>  /*
>   * Helper functions that are the same for both PPC64 and PPC32.
>   */
> -static int test_24bit_addr(unsigned long ip, unsigned long addr)
> +static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr)
>  {
>  	addr = ppc_function_entry((void *)addr);
>  
>  	/* use the create_branch to verify that this offset can be branched */
> -	return create_branch((unsigned int *)ip, addr, 0);
> +	return create_branch((ppc_inst *)ip, addr, 0);
>  }
>  
> -static int is_bl_op(unsigned int op)
> +static int is_bl_op(ppc_inst op)
>  {
>  	return (op & 0xfc000003) == 0x48000001;
>  }
>  
> -static int is_b_op(unsigned int op)
> +static int is_b_op(ppc_inst op)
>  {
>  	return (op & 0xfc000003) == 0x48000000;
>  }
>  
> -static unsigned long find_bl_target(unsigned long ip, unsigned int op)
> +static unsigned long find_bl_target(unsigned long ip, ppc_inst op)
>  {
>  	int offset;
>  
> @@ -125,7 +126,7 @@ __ftrace_make_nop(struct module *mod,
>  {
>  	unsigned long entry, ptr, tramp;
>  	unsigned long ip = rec->ip;
> -	unsigned int op, pop;
> +	ppc_inst op, pop;
>  
>  	/* read where this goes */
>  	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> @@ -204,7 +205,7 @@ __ftrace_make_nop(struct module *mod,
>  	}
>  #endif /* CONFIG_MPROFILE_KERNEL */
>  
> -	if (patch_instruction((unsigned int *)ip, pop)) {
> +	if (patch_instruction((ppc_inst *)ip, pop)) {
>  		pr_err("Patching NOP failed.\n");
>  		return -EPERM;
>  	}
> @@ -217,7 +218,7 @@ static int
>  __ftrace_make_nop(struct module *mod,
>  		  struct dyn_ftrace *rec, unsigned long addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	unsigned int jmp[4];
>  	unsigned long ip = rec->ip;
>  	unsigned long tramp;
> @@ -276,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
>  
>  	op = PPC_INST_NOP;
>  
> -	if (patch_instruction((unsigned int *)ip, op))
> +	if (patch_instruction((ppc_inst *)ip, op))
>  		return -EPERM;
>  
>  	return 0;
> @@ -322,7 +323,8 @@ static int add_ftrace_tramp(unsigned long tramp)
>   */
>  static int setup_mcount_compiler_tramp(unsigned long tramp)
>  {
> -	int i, op;
> +	int i;
> +	ppc_inst op;
>  	unsigned long ptr;
>  	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
>  
> @@ -388,7 +390,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> tramp)
>  static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long
> addr)
>  {
>  	unsigned long tramp, ip = rec->ip;
> -	unsigned int op;
> +	ppc_inst op;
>  
>  	/* Read where this goes */
>  	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> @@ -416,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  		}
>  	}
>  
> -	if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) {
> +	if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) {
>  		pr_err("Patching NOP failed.\n");
>  		return -EPERM;
>  	}
> @@ -428,7 +430,7 @@ int ftrace_make_nop(struct module *mod,
>  		    struct dyn_ftrace *rec, unsigned long addr)
>  {
>  	unsigned long ip = rec->ip;
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -481,7 +483,7 @@ int ftrace_make_nop(struct module *mod,
>   */
>  #ifndef CONFIG_MPROFILE_KERNEL
>  static int
> -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
> +expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
>  {
>  	/*
>  	 * We expect to see:
> @@ -510,7 +512,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> unsigned int op1)
>  static int
>  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
> -	unsigned int op[2];
> +	ppc_inst op[2];
>  	void *ip = (void *)rec->ip;
>  	unsigned long entry, ptr, tramp;
>  	struct module *mod = rec->arch.mod;
> @@ -574,7 +576,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  static int
>  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	unsigned long ip = rec->ip;
>  
>  	/* read where this goes */
> @@ -594,7 +596,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  	}
>  
>  	/* create the branch to the trampoline */
> -	op = create_branch((unsigned int *)ip,
> +	op = create_branch((ppc_inst *)ip,
>  			   rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
>  	if (!op) {
>  		pr_err("REL24 out of range!\n");
> @@ -613,7 +615,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  
>  static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long
> addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	void *ip = (void *)rec->ip;
>  	unsigned long tramp, entry, ptr;
>  
> @@ -661,7 +663,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
>  	unsigned long ip = rec->ip;
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -700,7 +702,7 @@ static int
>  __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
>  					unsigned long addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	unsigned long ip = rec->ip;
>  	unsigned long entry, ptr, tramp;
>  	struct module *mod = rec->arch.mod;
> @@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  	/* The new target may be within range */
>  	if (test_24bit_addr(ip, addr)) {
>  		/* within range */
> -		if (patch_branch((unsigned int *)ip, addr, BRANCH_SET_LINK)) {
> +		if (patch_branch((ppc_inst *)ip, addr, BRANCH_SET_LINK)) {
>  			pr_err("REL24 out of range!\n");
>  			return -EINVAL;
>  		}
> @@ -776,7 +778,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  	}
>  
>  	/* Ensure branch is within 24 bits */
> -	if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> +	if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
>  		pr_err("Branch out of range\n");
>  		return -EINVAL;
>  	}
> @@ -794,7 +796,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  			unsigned long addr)
>  {
>  	unsigned long ip = rec->ip;
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -834,7 +836,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  int ftrace_update_ftrace_func(ftrace_func_t func)
>  {
>  	unsigned long ip = (unsigned long)(&ftrace_call);
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  	int ret;
>  
>  	old = *(unsigned int *)&ftrace_call;
> @@ -919,7 +921,7 @@ int ftrace_enable_ftrace_graph_caller(void)
>  	unsigned long ip = (unsigned long)(&ftrace_graph_call);
>  	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
>  	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	old = ftrace_call_replace(ip, stub, 0);
>  	new = ftrace_call_replace(ip, addr, 0);
> @@ -932,7 +934,7 @@ int ftrace_disable_ftrace_graph_caller(void)
>  	unsigned long ip = (unsigned long)(&ftrace_graph_call);
>  	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
>  	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	old = ftrace_call_replace(ip, addr, 0);
>  	new = ftrace_call_replace(ip, stub, 0);
> diff --git a/arch/powerpc/kvm/emulate_loadstore.c
> b/arch/powerpc/kvm/emulate_loadstore.c
> index 1139bc56e004..1c9bcbfeb924 100644
> --- a/arch/powerpc/kvm/emulate_loadstore.c
> +++ b/arch/powerpc/kvm/emulate_loadstore.c
> @@ -21,6 +21,7 @@
>  #include <asm/disassemble.h>
>  #include <asm/ppc-opcode.h>
>  #include <asm/sstep.h>
> +#include <asm/inst.h>
>  #include "timing.h"
>  #include "trace.h"
>  
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index 3345f039a876..8492b9e2b8db 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -17,9 +17,10 @@
>  #include <asm/page.h>
>  #include <asm/code-patching.h>
>  #include <asm/setup.h>
> +#include <asm/inst.h>
>  
> -static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
> -			       unsigned int *patch_addr)
> +static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
> +			       ppc_inst *patch_addr)
>  {
>  	int err = 0;
>  
> @@ -33,7 +34,7 @@ static int __patch_instruction(unsigned int *exec_addr,
> unsigned int instr,
>  	return 0;
>  }
>  
> -int raw_patch_instruction(unsigned int *addr, unsigned int instr)
> +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
>  {
>  	return __patch_instruction(addr, instr, addr);
>  }
> @@ -136,10 +137,10 @@ static inline int unmap_patch_area(unsigned long addr)
>  	return 0;
>  }
>  
> -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
>  {
>  	int err;
> -	unsigned int *patch_addr = NULL;
> +	ppc_inst *patch_addr = NULL;
>  	unsigned long flags;
>  	unsigned long text_poke_addr;
>  	unsigned long kaddr = (unsigned long)addr;
> @@ -176,7 +177,7 @@ static int do_patch_instruction(unsigned int *addr,
> unsigned int instr)
>  }
>  #else /* !CONFIG_STRICT_KERNEL_RWX */
>  
> -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
>  {
>  	return raw_patch_instruction(addr, instr);
>  }
> @@ -194,7 +195,7 @@ int patch_instruction(unsigned int *addr, unsigned int
> instr)
>  }
>  NOKPROBE_SYMBOL(patch_instruction);
>  
> -int patch_branch(unsigned int *addr, unsigned long target, int flags)
> +int patch_branch(ppc_inst *addr, unsigned long target, int flags)
>  {
>  	return patch_instruction(addr, create_branch(addr, target, flags));
>  }
> @@ -225,7 +226,7 @@ bool is_offset_in_branch_range(long offset)
>   * Helper to check if a given instruction is a conditional branch
>   * Derived from the conditional checks in analyse_instr()
>   */
> -bool is_conditional_branch(unsigned int instr)
> +bool is_conditional_branch(ppc_inst instr)
>  {
>  	unsigned int opcode = instr >> 26;
>  
> @@ -243,10 +244,10 @@ bool is_conditional_branch(unsigned int instr)
>  }
>  NOKPROBE_SYMBOL(is_conditional_branch);
>  
> -unsigned int create_branch(const unsigned int *addr,
> +ppc_inst create_branch(const ppc_inst *addr,
>  			   unsigned long target, int flags)
>  {
> -	unsigned int instruction;
> +	ppc_inst instruction;
>  	long offset;
>  
>  	offset = target;
> @@ -266,7 +267,7 @@ unsigned int create_branch(const unsigned int *addr,
>  unsigned int create_cond_branch(const unsigned int *addr,
>  				unsigned long target, int flags)
>  {
> -	unsigned int instruction;
> +	ppc_inst instruction;
>  	long offset;
>  
>  	offset = target;
> @@ -283,22 +284,22 @@ unsigned int create_cond_branch(const unsigned int
> *addr,
>  	return instruction;
>  }
>  
> -static unsigned int branch_opcode(unsigned int instr)
> +static unsigned int branch_opcode(ppc_inst instr)
>  {
>  	return (instr >> 26) & 0x3F;
>  }
>  
> -static int instr_is_branch_iform(unsigned int instr)
> +static int instr_is_branch_iform(ppc_inst instr)
>  {
>  	return branch_opcode(instr) == 18;
>  }
>  
> -static int instr_is_branch_bform(unsigned int instr)
> +static int instr_is_branch_bform(ppc_inst instr)
>  {
>  	return branch_opcode(instr) == 16;
>  }
>  
> -int instr_is_relative_branch(unsigned int instr)
> +int instr_is_relative_branch(ppc_inst instr)
>  {
>  	if (instr & BRANCH_ABSOLUTE)
>  		return 0;
> @@ -306,12 +307,12 @@ int instr_is_relative_branch(unsigned int instr)
>  	return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
>  }
>  
> -int instr_is_relative_link_branch(unsigned int instr)
> +int instr_is_relative_link_branch(ppc_inst instr)
>  {
>  	return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
>  }
>  
> -static unsigned long branch_iform_target(const unsigned int *instr)
> +static unsigned long branch_iform_target(const ppc_inst *instr)
>  {
>  	signed long imm;
>  
> @@ -327,7 +328,7 @@ static unsigned long branch_iform_target(const unsigned
> int *instr)
>  	return (unsigned long)imm;
>  }
>  
> -static unsigned long branch_bform_target(const unsigned int *instr)
> +static unsigned long branch_bform_target(const ppc_inst *instr)
>  {
>  	signed long imm;
>  
> @@ -343,7 +344,7 @@ static unsigned long branch_bform_target(const unsigned
> int *instr)
>  	return (unsigned long)imm;
>  }
>  
> -unsigned long branch_target(const unsigned int *instr)
> +unsigned long branch_target(const ppc_inst *instr)
>  {
>  	if (instr_is_branch_iform(*instr))
>  		return branch_iform_target(instr);
> @@ -353,7 +354,7 @@ unsigned long branch_target(const unsigned int *instr)
>  	return 0;
>  }
>  
> -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
> +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr)
>  {
>  	if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
>  		return branch_target(instr) == addr;
> @@ -361,7 +362,7 @@ int instr_is_branch_to_addr(const unsigned int *instr,
> unsigned long addr)
>  	return 0;
>  }
>  
> -unsigned int translate_branch(const unsigned int *dest, const unsigned int
> *src)
> +ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
>  {
>  	unsigned long target;
>  
> @@ -403,7 +404,7 @@ static void __init test_trampoline(void)
>  
>  static void __init test_branch_iform(void)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  	unsigned long addr;
>  
>  	addr = (unsigned long)&instr;
> @@ -478,11 +479,11 @@ static void __init test_branch_iform(void)
>  
>  static void __init test_create_function_call(void)
>  {
> -	unsigned int *iptr;
> +	ppc_inst *iptr;
>  	unsigned long dest;
>  
>  	/* Check we can create a function call */
> -	iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> +	iptr = (ppc_inst *)ppc_function_entry(test_trampoline);
>  	dest = ppc_function_entry(test_create_function_call);
>  	patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
>  	check(instr_is_branch_to_addr(iptr, dest));
> @@ -491,7 +492,8 @@ static void __init test_create_function_call(void)
>  static void __init test_branch_bform(void)
>  {
>  	unsigned long addr;
> -	unsigned int *iptr, instr, flags;
> +	ppc_inst *iptr, instr;
> +	unsigned int flags;
>  
>  	iptr = &instr;
>  	addr = (unsigned long)iptr;
> @@ -561,7 +563,7 @@ static void __init test_branch_bform(void)
>  static void __init test_translate_branch(void)
>  {
>  	unsigned long addr;
> -	unsigned int *p, *q;
> +	ppc_inst *p, *q;
>  	void *buf;
>  
>  	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index c077acb983a1..1d9c766a89fe 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1, long
> v2)
>   * otherwise.
>   */
>  int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> -		  unsigned int instr)
> +		  ppc_inst instr)
>  {
>  	unsigned int opcode, ra, rb, rc, rd, spr, u;
>  	unsigned long int imm;
> @@ -3101,7 +3101,7 @@ NOKPROBE_SYMBOL(emulate_loadstore);
>   * or -1 if the instruction is one that should not be stepped,
>   * such as an rfid, or a mtmsrd that would clear MSR_RI.
>   */
> -int emulate_step(struct pt_regs *regs, unsigned int instr)
> +int emulate_step(struct pt_regs *regs, ppc_inst instr)
>  {
>  	struct instruction_op op;
>  	int r, err, type;
> diff --git a/arch/powerpc/lib/test_emulate_step.c
> b/arch/powerpc/lib/test_emulate_step.c
> index 42347067739c..158efc8a0f53 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -460,7 +460,7 @@ struct compute_test {
>  	struct {
>  		char *descr;
>  		unsigned long flags;
> -		unsigned int instr;
> +		ppc_inst instr;
>  		struct pt_regs regs;
>  	} subtests[MAX_SUBTESTS + 1];
>  };
> @@ -841,7 +841,7 @@ static struct compute_test compute_tests[] = {
>  };
>  
>  static int __init emulate_compute_instr(struct pt_regs *regs,
> -					unsigned int instr)
> +					ppc_inst instr)
>  {
>  	struct instruction_op op;
>  
> @@ -859,7 +859,7 @@ static int __init emulate_compute_instr(struct pt_regs
> *regs,
>  }
>  
>  static int __init execute_compute_instr(struct pt_regs *regs,
> -					unsigned int instr)
> +					ppc_inst instr)
>  {
>  	extern int exec_instr(struct pt_regs *regs);
>  	extern s32 patch__exec_instr;
> @@ -890,7 +890,8 @@ static void __init run_tests_compute(void)
>  	unsigned long flags;
>  	struct compute_test *test;
>  	struct pt_regs *regs, exp, got;
> -	unsigned int i, j, k, instr;
> +	unsigned int i, j, k;
> +	ppc_inst instr;
>  	bool ignore_gpr, ignore_xer, ignore_ccr, passed;
>  
>  	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 7875d1a37770..a0bc442f9557 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
>  static void insert_bpts(void)
>  {
>  	int i;
> -	unsigned int instr;
> +	ppc_inst instr;
>  	struct bpt *bp;
>  
>  	bp = bpts;
> @@ -914,7 +914,7 @@ static void insert_bpts(void)
>  		patch_instruction(bp->instr, instr);
>  		if (bp->enabled & BP_CIABR)
>  			continue;
> -		if (patch_instruction((unsigned int *)bp->address,
> +		if (patch_instruction((ppc_inst *)bp->address,
>  							bpinstr) != 0) {
>  			printf("Couldn't write instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
> @@ -943,7 +943,7 @@ static void remove_bpts(void)
>  {
>  	int i;
>  	struct bpt *bp;
> -	unsigned instr;
> +	ppc_inst instr;
>  
>  	bp = bpts;
>  	for (i = 0; i < NBPTS; ++i, ++bp) {
> @@ -952,7 +952,7 @@ static void remove_bpts(void)
>  		if (mread(bp->address, &instr, 4) == 4
>  		    && instr == bpinstr
>  		    && patch_instruction(
> -			(unsigned int *)bp->address, bp->instr[0]) != 0)
> +			(ppc_inst *)bp->address, bp->instr[0]) != 0)
>  			printf("Couldn't remove breakpoint at %lx\n",
>  			       bp->address);
>  	}
> @@ -1159,7 +1159,7 @@ static int do_step(struct pt_regs *regs)
>   */
>  static int do_step(struct pt_regs *regs)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  	int stepped;
>  
>  	force_enable_xmon();
> @@ -1325,7 +1325,7 @@ csum(void)
>   */
>  static long check_bp_loc(unsigned long addr)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  
>  	addr &= ~3;
>  	if (!is_kernel_addr(addr)) {


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 00/16] Initial Prefixed Instruction support
  2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
                   ` (15 preceding siblings ...)
  2020-03-20  5:18 ` [PATCH v4 16/16] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
@ 2020-03-23  6:18 ` Nicholas Piggin
  2020-03-23  9:25   ` Jordan Niethe
  16 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:18 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:17 pm:
> A future revision of the ISA will introduce prefixed instructions. A
> prefixed instruction is composed of a 4-byte prefix followed by a
> 4-byte suffix.
> 
> All prefixes have the major opcode 1. A prefix will never be a valid
> word instruction. A suffix may be an existing word instruction or a
> new instruction.
> 
> This series enables prefixed instructions and extends the instruction
> emulation to support them. Then the places where prefixed instructions
> might need to be emulated are updated.
> 
> The series is based on top of:
> https://patchwork.ozlabs.org/patch/1232619/ as this will effect
> kprobes.
> 
> v4 is based on feedback from Nick Piggins, Christophe Leroy and Daniel Axtens.
> The major changes:
>     - Move xmon breakpoints from data section to text section
>     - Introduce a data type for instructions on powerpc

Thanks for doing this, looks like a lot of work, I hope it works out :)

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction()
  2020-03-20  5:17 ` [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
@ 2020-03-23  6:19   ` Nicholas Piggin
  0 siblings, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:19 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:17 pm:
> For modifying instructions in xmon, patch_instruction() can serve the
> same role that store_inst() is performing with the advantage of not
> being specific to xmon. In some places patch_instruction() is already
> being using followed by store_inst(). In these cases just remove the
> store_inst(). Otherwise replace store_inst() with patch_instruction().

LGTM

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: Read into a local variable
> ---
>  arch/powerpc/xmon/xmon.c | 18 +++++-------------
>  1 file changed, 5 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index e8c84d265602..02e3bd62cab4 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -325,11 +325,6 @@ static inline void sync(void)
>  	asm volatile("sync; isync");
>  }
>  
> -static inline void store_inst(void *p)
> -{
> -	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
> -}
> -
>  static inline void cflush(void *p)
>  {
>  	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
> @@ -881,8 +876,7 @@ static struct bpt *new_breakpoint(unsigned long a)
>  	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
>  		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
>  			bp->address = a;
> -			bp->instr[1] = bpinstr;
> -			store_inst(&bp->instr[1]);
> +			patch_instruction(&bp->instr[1], bpinstr);
>  			return bp;
>  		}
>  	}
> @@ -894,25 +888,26 @@ static struct bpt *new_breakpoint(unsigned long a)
>  static void insert_bpts(void)
>  {
>  	int i;
> +	unsigned int instr;
>  	struct bpt *bp;
>  
>  	bp = bpts;
>  	for (i = 0; i < NBPTS; ++i, ++bp) {
>  		if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
>  			continue;
> -		if (mread(bp->address, &bp->instr[0], 4) != 4) {
> +		if (mread(bp->address, &instr, 4) != 4) {
>  			printf("Couldn't read instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
>  			bp->enabled = 0;
>  			continue;
>  		}
> -		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
> +		if (IS_MTMSRD(instr) || IS_RFID(instr)) {
>  			printf("Breakpoint at %lx is on an mtmsrd or rfid "
>  			       "instruction, disabling it\n", bp->address);
>  			bp->enabled = 0;
>  			continue;
>  		}
> -		store_inst(&bp->instr[0]);
> +		patch_instruction(bp->instr, instr);
>  		if (bp->enabled & BP_CIABR)
>  			continue;
>  		if (patch_instruction((unsigned int *)bp->address,
> @@ -922,7 +917,6 @@ static void insert_bpts(void)
>  			bp->enabled &= ~BP_TRAP;
>  			continue;
>  		}
> -		store_inst((void *)bp->address);
>  	}
>  }
>  
> @@ -957,8 +951,6 @@ static void remove_bpts(void)
>  			(unsigned int *)bp->address, bp->instr[0]) != 0)
>  			printf("Couldn't remove breakpoint at %lx\n",
>  			       bp->address);
> -		else
> -			store_inst((void *)bp->address);
>  	}
>  }
>  
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 02/16] xmon: Move out-of-line instructions to text section
  2020-03-20  5:17 ` [PATCH v4 02/16] xmon: Move out-of-line instructions to text section Jordan Niethe
  2020-03-23  5:59   ` Balamuruhan S
  2020-03-23  6:05   ` Balamuruhan S
@ 2020-03-23  6:22   ` Nicholas Piggin
  2 siblings, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:22 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:17 pm:
> To execute an instruction out of line after a breakpoint, the NIP is set
> to the address of struct bpt::instr. Here a copy of the instruction that
> was replaced with a breakpoint is kept, along with a trap so normal flow
> can be resumed after XOLing. The struct bpt's are located within the
> data section. This is problematic as the data section may be marked as
> no execute.
> 
> Instead of each struct bpt holding the instructions to be XOL'd, make a
> new array, bpt_table[], with enough space to hold instructions for the
> number of supported breakpoints. Place this array in the text section.
> Make struct bpt::instr a pointer to the instructions in bpt_table[]
> associated with that breakpoint. This association is a simple mapping:
> bpts[n] -> bpt_table[n * words per breakpoint]. Currently we only need
> the copied instruction followed by a trap, so 2 words per breakpoint.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> ---
> v4: New to series
> ---
>  arch/powerpc/kernel/vmlinux.lds.S |  2 +-
>  arch/powerpc/xmon/xmon.c          | 22 +++++++++++++---------
>  2 files changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
> index b4c89a1acebb..e90845b8c300 100644
> --- a/arch/powerpc/kernel/vmlinux.lds.S
> +++ b/arch/powerpc/kernel/vmlinux.lds.S
> @@ -86,7 +86,7 @@ SECTIONS
>  		ALIGN_FUNCTION();
>  #endif
>  		/* careful! __ftr_alt_* sections need to be close to .text */
> -		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text);
> +		*(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text .text.xmon_bpts);
>  #ifdef CONFIG_PPC64
>  		*(.tramp.ftrace.text);
>  #endif
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 02e3bd62cab4..7875d1a37770 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -97,7 +97,7 @@ static long *xmon_fault_jmp[NR_CPUS];
>  /* Breakpoint stuff */
>  struct bpt {
>  	unsigned long	address;
> -	unsigned int	instr[2];
> +	unsigned int	*instr;
>  	atomic_t	ref_count;
>  	int		enabled;
>  	unsigned long	pad;
> @@ -109,6 +109,7 @@ struct bpt {
>  #define BP_DABR		4
>  
>  #define NBPTS	256
> +#define BPT_WORDS	2
>  static struct bpt bpts[NBPTS];
>  static struct bpt dabr;
>  static struct bpt *iabr;
> @@ -116,6 +117,8 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
>  
>  #define BP_NUM(bp)	((bp) - bpts + 1)
>  
> +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS];
> +
>  /* Prototypes */
>  static int cmds(struct pt_regs *);
>  static int mread(unsigned long, void *, int);
> @@ -852,16 +855,16 @@ static struct bpt *at_breakpoint(unsigned long pc)
>  static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
>  {
>  	unsigned long off;
> +	unsigned long bp_off;
>  
> -	off = nip - (unsigned long) bpts;
> -	if (off >= sizeof(bpts))
> +	off = nip - (unsigned long) bpt_table;
> +	if (off >= sizeof(bpt_table))
>  		return NULL;
> -	off %= sizeof(struct bpt);
> -	if (off != offsetof(struct bpt, instr[0])
> -	    && off != offsetof(struct bpt, instr[1]))
> +	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> +	if (bp_off != 0 && bp_off != 4)
>  		return NULL;
> -	*offp = off - offsetof(struct bpt, instr[0]);
> -	return (struct bpt *) (nip - off);
> +	*offp = bp_off;
> +	return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
>  }
>  
>  static struct bpt *new_breakpoint(unsigned long a)
> @@ -876,7 +879,8 @@ static struct bpt *new_breakpoint(unsigned long a)
>  	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
>  		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
>  			bp->address = a;
> -			patch_instruction(&bp->instr[1], bpinstr);
> +			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> +			patch_instruction(bp->instr + 1, bpinstr);
>  			return bp;
>  		}
>  	}
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-20  5:17 ` [PATCH v4 03/16] powerpc: Use a datatype for instructions Jordan Niethe
  2020-03-23  6:07   ` Balamuruhan S
@ 2020-03-23  6:23   ` Nicholas Piggin
  2020-03-23  9:28     ` Jordan Niethe
  2020-04-01 10:32   ` Balamuruhan S
  2 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:23 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:17 pm:
> Currently unsigned ints are used to represent instructions on powerpc.
> This has worked well as instructions have always been 4 byte words.
> However, a future ISA version will introduce some changes to
> instructions that mean this scheme will no longer work as well. This
> change is Prefixed Instructions. A prefixed instruction is made up of a
> word prefix followed by a word suffix to make an 8 byte double word
> instruction. No matter the endianess of the system the prefix always
> comes first. Prefixed instructions are only planned for powerpc64.
> 
> Introduce a ppc_inst type to represent both prefixed and word
> instructions on powerpc64 while keeping it possible to exclusively have
> word instructions on powerpc32, A latter patch will expand the type to
> include prefixed instructions but for now just typedef it to a u32.
> 
> Later patches will introduce helper functions and macros for
> manipulating the instructions so that powerpc64 and powerpc32 might
> maintain separate type definitions.

ppc_inst_t I would slightly prefer for a typedef like this.

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s
  2020-03-20  5:17 ` [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
@ 2020-03-23  6:26   ` Nicholas Piggin
  2020-03-23  9:29     ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:26 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:17 pm:
> In preparation for instructions having a more complex data type start
> using a macro, PPC_INST(), for making an instruction out of a u32.
> Currently this does nothing, but it will allow for creating a data type
> that can represent prefixed instructions.

Where is the macro? And, can it be a static inline (and lowercase) 
instead? No big deal if not.

Thanks,
Nick


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 05/16] powerpc: Use a function for masking instructions
  2020-03-20  5:17 ` [PATCH v4 05/16] powerpc: Use a function for masking instructions Jordan Niethe
@ 2020-03-23  6:37   ` Nicholas Piggin
  2020-03-23  9:31     ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:37 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:17 pm:
> In preparation for using an instruction data type that can not be used
> directly with the '&' operator, use a function to mask instructions.

Hmm. ppc_inst_mask isn't such a good interface I think. It takes a
ppc_inst and a mask, you would expect it to return a ppc_inst, probably
with some part of its value anded with your mask value but not entirely
clear.

I would have a ppc_inst_val that is a more mechanical replacement and
lets you do more things with it, although I like the other helpers you
add later. Oh you've added ppc_inst_word further down. Why not use that
here intead of ppc_inst_mask()?

Thanks,
Nick


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality
  2020-03-20  5:18 ` [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality Jordan Niethe
@ 2020-03-23  6:43   ` Nicholas Piggin
  2020-03-23  9:31     ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:43 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:18 pm:
> In preparation for an instruction data type that can not be directly
> used with the '==' operator use functions for checking equality and
> nullity.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>  arch/powerpc/kernel/optprobes.c      |  2 +-
>  arch/powerpc/kernel/trace/ftrace.c   | 33 +++++++++++++++-------------
>  arch/powerpc/lib/code-patching.c     | 16 +++++++-------
>  arch/powerpc/lib/feature-fixups.c    |  2 +-
>  arch/powerpc/lib/test_emulate_step.c |  4 ++--
>  arch/powerpc/xmon/xmon.c             |  4 ++--
>  6 files changed, 32 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index 1025a7a3b3a8..6027425a85f2 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -259,7 +259,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
>  				(unsigned long)emulate_step_addr,
>  				BRANCH_SET_LINK);
>  
> -	if (!branch_op_callback || !branch_emulate_step)
> +	if (ppc_inst_null(branch_op_callback) || ppc_inst_null(branch_emulate_step))

Is an instruction null, or zeroes?

Oh, most of this comes from create_branch and things. Hmm, would rather
see those functions modified to take a &insn and return an int err.


> @@ -437,7 +438,7 @@ int ftrace_make_nop(struct module *mod,
>  	 * then we had to use a trampoline to make the call.
>  	 * Otherwise just update the call site.
>  	 */
> -	if (test_24bit_addr(ip, addr)) {
> +	if (!ppc_inst_null(test_24bit_addr(ip, addr))) {
>  		/* within range */
>  		old = ftrace_call_replace(ip, addr, 1);
>  		new = PPC_INST(PPC_INST_NOP);

test_24bit_addr shouldn't be passing a ppc_inst back, but a bool.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code
  2020-03-20  5:17 ` [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code Jordan Niethe
@ 2020-03-23  6:54   ` Balamuruhan S
  2020-03-23  9:35     ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23  6:54 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> In preparation for using a data type for instructions that can not be
> directly used with the '>>' operator use a function for getting the op
> code of an instruction.

we need to adopt this in sstep.c and vecemu.c

-- Bala
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/kernel/align.c      | 4 ++--
>  arch/powerpc/lib/code-patching.c | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index 38542fffa179..77c49dfdc1b4 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -313,8 +313,8 @@ int fix_alignment(struct pt_regs *regs)
>  	}
>  
>  #ifdef CONFIG_SPE
> -	if ((instr >> 26) == 0x4) {
> -		int reg = (instr >> 21) & 0x1f;
> +	if (ppc_inst_opcode(instr) == 0x4) {
> +		int reg = (ppc_inst_word(instr) >> 21) & 0x1f;
>  		PPC_WARN_ALIGNMENT(spe, regs);
>  		return emulate_spe(regs, reg, instr);
>  	}
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index e2ba23fd6f4d..04a303c059e2 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -228,7 +228,7 @@ bool is_offset_in_branch_range(long offset)
>   */
>  bool is_conditional_branch(ppc_inst instr)
>  {
> -	unsigned int opcode = instr >> 26;
> +	unsigned int opcode = ppc_inst_opcode(instr);
>  
>  	if (opcode == 16)       /* bc, bca, bcl, bcla */
>  		return true;
> @@ -286,7 +286,7 @@ unsigned int create_cond_branch(const unsigned int *addr,
>  
>  static unsigned int branch_opcode(ppc_inst instr)
>  {
> -	return (instr >> 26) & 0x3F;
> +	return ppc_inst_opcode(instr) & 0x3F;
>  }
>  
>  static int instr_is_branch_iform(ppc_inst instr)


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type
  2020-03-20  5:18 ` [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
@ 2020-03-23  6:58   ` Nicholas Piggin
  2020-03-23  7:33   ` Nicholas Piggin
  2020-03-30  9:05   ` Alistair Popple
  2 siblings, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  6:58 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:18 pm:
> For powerpc64, redefine the ppc_inst type so both word and prefixed
> instructions can be represented. On powerpc32 the type will remain the
> same.  Update places which had assumed instructions to be 4 bytes long.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/include/asm/code-patching.h | 10 +--
>  arch/powerpc/include/asm/inst.h          | 90 ++++++++++++++++++++++++
>  arch/powerpc/include/asm/kprobes.h       |  2 +-
>  arch/powerpc/include/asm/sstep.h         |  4 ++
>  arch/powerpc/include/asm/uaccess.h       | 22 ++++++
>  arch/powerpc/include/asm/uprobes.h       |  2 +-
>  arch/powerpc/kernel/align.c              |  5 +-
>  arch/powerpc/kernel/hw_breakpoint.c      |  2 +-
>  arch/powerpc/kernel/kprobes.c            |  7 +-
>  arch/powerpc/kernel/optprobes.c          | 42 ++++++-----
>  arch/powerpc/kernel/optprobes_head.S     |  3 +
>  arch/powerpc/kernel/trace/ftrace.c       | 19 ++++-
>  arch/powerpc/kernel/uprobes.c            |  2 +-
>  arch/powerpc/lib/code-patching.c         | 22 ++++--
>  arch/powerpc/lib/sstep.c                 |  4 +-
>  arch/powerpc/xmon/xmon.c                 | 38 +++++++---
>  16 files changed, 221 insertions(+), 53 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
> index 68bd9db334bd..bd41e1558707 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -25,11 +25,11 @@
>  bool is_offset_in_branch_range(long offset);
>  ppc_inst create_branch(const ppc_inst *addr,
>  			   unsigned long target, int flags);
> -unsigned int create_cond_branch(const ppc_inst *addr,
> +ppc_inst create_cond_branch(const void *addr,
>  				unsigned long target, int flags);
> -int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> -int patch_instruction(ppc_inst *addr, ppc_inst instr);
> -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
> +int patch_branch(void *addr, unsigned long target, int flags);
> +int patch_instruction(void *addr, ppc_inst instr);
> +int raw_patch_instruction(void *addr, ppc_inst instr);
>  
>  static inline unsigned long patch_site_addr(s32 *site)
>  {
> @@ -60,7 +60,7 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
>  int instr_is_relative_branch(ppc_inst instr);
>  int instr_is_relative_link_branch(ppc_inst instr);
>  int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> -unsigned long branch_target(const ppc_inst *instr);
> +unsigned long branch_target(const void *instr);
>  ppc_inst translate_branch(const ppc_inst *dest,
>  			      const ppc_inst *src);
>  extern bool is_conditional_branch(ppc_inst instr);
> diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> index 7c8596ee411e..1a40b0a71128 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -6,6 +6,95 @@
>   * Instruction data type for POWER
>   */
>  
> +#ifdef __powerpc64__
> +
> +typedef struct ppc_inst {
> +	union {
> +		struct {
> +			u32 word;
> +			u32 pad;
> +		} __packed;
> +		struct {
> +			u32 prefix;
> +			u32 suffix;
> +		} __packed;
> +	};
> +} ppc_inst;
> +
> +#define PPC_INST(x) ((ppc_inst) { .word = (x), .pad = 0 })
> +#define PPC_INST_PREFIXED(x, y) ((ppc_inst) { .prefix = (x), .suffix = (y) })
> +
> +static inline int ppc_inst_opcode(ppc_inst x)
> +{
> +	return x.word >> 26;
> +}
> +
> +static inline bool ppc_inst_prefixed(ppc_inst x) {
> +	return ppc_inst_opcode(x) == 1;
> +}
> +
> +static inline int ppc_inst_len(ppc_inst x)
> +{
> +	if (ppc_inst_prefixed(x))
> +		return 8;
> +	else
> +		return 4;
> +}
> +
> +static inline u32 ppc_inst_word(ppc_inst x)
> +{
> +	return x.word;
> +}
> +
> +static inline u32 ppc_inst_prefix(ppc_inst x)
> +{
> +	return x.prefix;
> +}
> +
> +static inline u32 ppc_inst_suffix(ppc_inst x)
> +{
> +	return x.suffix;
> +}
> +
> +
> +static inline ppc_inst ppc_inst_read(const void *ptr)
> +{
> +	ppc_inst inst;
> +	inst.word = *(u32 *)ptr;
> +	if (ppc_inst_prefixed(inst))
> +		inst.suffix = *((u32 *)ptr + 1);
> +	else
> +		inst.pad = 0;
> +	return inst;
> +}
> +
> +static inline void ppc_inst_write(ppc_inst *ptr, ppc_inst x)
> +{
> +	if (ppc_inst_prefixed(x)) {
> +		*(u32 *)ptr = x.prefix;
> +		*((u32 *)ptr + 1) = x.suffix;
> +	} else {
> +		*(u32 *)ptr = x.word;
> +	}
> +}
> +
> +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
> +{
> +	return !memcmp(&x, &y, sizeof(struct ppc_inst));
> +}
> +
> +static inline bool ppc_inst_null(ppc_inst x)
> +{
> +	return x.word == 0 && x.pad == 0;
> +}
> +
> +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
> +{
> +	return ppc_inst_word(x) & mask;
> +}
> +
> +#else /* !__powerpc64__ */
> +
>  typedef u32 ppc_inst;
>  
>  #define PPC_INST(x) (x)
> @@ -50,4 +139,5 @@ static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
>  	return ppc_inst_word(x) & mask;
>  }
>  
> +#endif /* __powerpc64__ */
>  #endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h
> index 66b3f2983b22..4fc0e15e23a5 100644
> --- a/arch/powerpc/include/asm/kprobes.h
> +++ b/arch/powerpc/include/asm/kprobes.h
> @@ -43,7 +43,7 @@ extern kprobe_opcode_t optprobe_template_ret[];
>  extern kprobe_opcode_t optprobe_template_end[];
>  
>  /* Fixed instruction size for powerpc */
> -#define MAX_INSN_SIZE		1
> +#define MAX_INSN_SIZE		2
>  #define MAX_OPTIMIZED_LENGTH	sizeof(kprobe_opcode_t)	/* 4 bytes */
>  #define MAX_OPTINSN_SIZE	(optprobe_template_end - optprobe_template_entry)
>  #define RELATIVEJUMP_SIZE	sizeof(kprobe_opcode_t)	/* 4 bytes */
> diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
> index ef5483288920..5eb825fb77cd 100644
> --- a/arch/powerpc/include/asm/sstep.h
> +++ b/arch/powerpc/include/asm/sstep.h
> @@ -90,11 +90,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 GETLENGTH(t)   (((t) & PREFIXED) ? 8 : 4)
>  
>  #define MKOP(t, f, s)	((t) | (f) | SIZE(s))
>  
> diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
> index 2f500debae21..dee4fa1cd3ec 100644
> --- a/arch/powerpc/include/asm/uaccess.h
> +++ b/arch/powerpc/include/asm/uaccess.h
> @@ -105,6 +105,28 @@ static inline int __access_ok(unsigned long addr, unsigned long size,
>  #define __put_user_inatomic(x, ptr) \
>  	__put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
>  
> +/*
> + * When reading an instruction iff it is a prefix, the suffix needs to be also
> + * loaded.
> + */
> +#define __get_user_instr(x, ptr)			\
> +({							\
> +	long __gui_ret = 0;				\
> +	__gui_ret = __get_user(x.prefix, (unsigned int __user *)ptr);		\
> +	if (!__gui_ret && ppc_inst_prefixed(x))		\
> +		__gui_ret = __get_user(x.suffix, (unsigned int __user *)ptr + 1);	\
> +	__gui_ret;					\
> +})
> +
> +#define __get_user_instr_inatomic(x, ptr)		\
> +({							\
> +	long __gui_ret = 0;				\
> +	__gui_ret = __get_user_inatomic(x.prefix, (unsigned int __user *)ptr);		\
> +	if (!__gui_ret && ppc_inst_prefixed(x))		\
> +		__gui_ret = __get_user_inatomic(x.suffix, (unsigned int __user *)ptr + 1);	\
> +	__gui_ret;					\
> +})
> +
>  extern long __put_user_bad(void);
>  
>  /*
> diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
> index fff3c5fc90b5..7896a7125fa9 100644
> --- a/arch/powerpc/include/asm/uprobes.h
> +++ b/arch/powerpc/include/asm/uprobes.h
> @@ -14,7 +14,7 @@
>  
>  typedef ppc_opcode_t uprobe_opcode_t;
>  
> -#define MAX_UINSN_BYTES		4
> +#define MAX_UINSN_BYTES		8
>  #define UPROBE_XOL_SLOT_BYTES	(MAX_UINSN_BYTES)
>  
>  /* The following alias is needed for reference from arch-agnostic code */
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index b246ca124931..110eadd85c58 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -303,13 +303,14 @@ int fix_alignment(struct pt_regs *regs)
>  	 */
>  	CHECK_FULL_REGS(regs);
>  
> -	if (unlikely(__get_user(instr, (unsigned int __user *)regs->nip)))
> +	if (unlikely(__get_user_instr(instr, (void __user *)regs->nip)))
>  		return -EFAULT;
>  	if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
>  		/* We don't handle PPC little-endian any more... */
>  		if (cpu_has_feature(CPU_FTR_PPC_LE))
>  			return -EIO;
> -		instr = PPC_INST(swab32(ppc_inst_word(instr)));
> +		instr = PPC_INST_PREFIXED(swab32(ppc_inst_word(instr)),
> +					  swab32(ppc_inst_suffix(instr)));
>  	}
>  
>  #ifdef CONFIG_SPE
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
> index f001de471b98..212e0abfda43 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -249,7 +249,7 @@ static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
>  	struct instruction_op op;
>  	unsigned long addr = info->address;
>  
> -	if (__get_user_inatomic(instr, (unsigned int *)regs->nip))
> +	if (__get_user_instr_inatomic(instr, (void __user*)regs->nip))
>  		goto fail;
>  
>  	ret = analyse_instr(&op, regs, instr);
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index f142d11d7b48..1a5370a3c7c8 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -153,7 +153,7 @@ NOKPROBE_SYMBOL(arch_arm_kprobe);
>  
>  void arch_disarm_kprobe(struct kprobe *p)
>  {
> -	patch_instruction(p->addr, PPC_INST(p->opcode));
> +	patch_instruction(p->addr, ppc_inst_read(p->ainsn.insn));
>  }
>  NOKPROBE_SYMBOL(arch_disarm_kprobe);
>  
> @@ -487,12 +487,13 @@ int kprobe_post_handler(struct pt_regs *regs)
>  {
>  	struct kprobe *cur = kprobe_running();
>  	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +	int len = ppc_inst_len(ppc_inst_read(cur->ainsn.insn));
>  
>  	if (!cur || user_mode(regs))
>  		return 0;
>  
>  	/* 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) {
> @@ -501,7 +502,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/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index 5b53c373373b..af6761859fba 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -158,38 +158,38 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr)
>  
>  /*
>   * Generate instructions to load provided immediate 64-bit value
> - * to register 'r3' and patch these instructions at 'addr'.
> + * to register 'reg' and patch these instructions at 'addr'.
>   */
> -void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
> +void patch_imm64_load_insns(unsigned long val, int reg, kprobe_opcode_t *addr)
>  {
> -	/* lis r3,(op)@highest */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(3) |
> +	/* lis reg,(op)@highest */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(reg) |
>  			  ((val >> 48) & 0xffff)));
>  	addr++;
>  
> -	/* ori r3,r3,(op)@higher */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | ((val >> 32) & 0xffff)));
> +	/* ori reg,reg,(op)@higher */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
>  	addr++;
>  
> -	/* rldicr r3,r3,32,31 */
> -	patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)));
> +	/* rldicr reg,reg,32,31 */
> +	patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | __PPC_SH64(32) | __PPC_ME64(31)));
>  	addr++;
>  
> -	/* oris r3,r3,(op)@h */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | ((val >> 16) & 0xffff)));
> +	/* oris reg,reg,(op)@h */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
>  	addr++;
>  
> -	/* ori r3,r3,(op)@l */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | (val & 0xffff)));
> +	/* ori reg,reg,(op)@l */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | (val & 0xffff)));
>  }
>  
>  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
>  {
> -	ppc_inst branch_op_callback, branch_emulate_step;
> +	ppc_inst branch_op_callback, branch_emulate_step, temp;
>  	kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
>  	long b_offset;
>  	unsigned long nip, size;
> @@ -239,7 +239,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
>  	 * Fixup the template with instructions to:
>  	 * 1. load the address of the actual probepoint
>  	 */
> -	patch_imm64_load_insns((unsigned long)op, buff + TMPL_OP_IDX);
> +	patch_imm64_load_insns((unsigned long)op, 3, buff + TMPL_OP_IDX);
>  
>  	/*
>  	 * 2. branch to optimized_callback() and emulate_step()
> @@ -268,7 +268,11 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
>  	/*
>  	 * 3. load instruction to be emulated into relevant register, and
>  	 */
> -	patch_imm32_load_insns(*(unsigned int *)p->ainsn.insn, buff + TMPL_INSN_IDX);
> +	temp = ppc_inst_read(p->ainsn.insn);
> +	patch_imm64_load_insns(ppc_inst_word(temp) |
> +			       ((u64)ppc_inst_suffix(temp) << 32),
> +			       4,
> +			       buff + TMPL_INSN_IDX);
>  
>  	/*
>  	 * 4. branch back from trampoline
> diff --git a/arch/powerpc/kernel/optprobes_head.S b/arch/powerpc/kernel/optprobes_head.S
> index cf383520843f..ff8ba4d3824d 100644
> --- a/arch/powerpc/kernel/optprobes_head.S
> +++ b/arch/powerpc/kernel/optprobes_head.S
> @@ -94,6 +94,9 @@ optprobe_template_insn:
>  	/* 2, Pass instruction to be emulated in r4 */
>  	nop
>  	nop
> +	nop
> +	nop
> +	nop
>  
>  	.global optprobe_template_call_emulate
>  optprobe_template_call_emulate:
> diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
> index ad451205f268..3b8655f57b4a 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -42,9 +42,24 @@
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
>  
>  static long
> -read_inst(ppc_inst *inst, const void *src)
> +read_inst(ppc_inst *p, const void *src)
>  {
> -	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> +	ppc_inst inst;
> +	long err;
> +
> +	err = probe_kernel_read((void *)&inst.prefix,
> +				src, MCOUNT_INSN_SIZE);
> +	if (err)
> +		return err;
> +
> +	if (ppc_inst_prefixed(inst))
> +		err = probe_kernel_read((void *)&inst.suffix,
> +					src + 4, MCOUNT_INSN_SIZE);
> +	if (err)
> +		return err;
> +
> +	ppc_inst_write(p, inst);
> +	return 0;
>  }
>  
>  static ppc_inst
> diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> index d1dff1dc3a11..3e4fbb5c1b1e 100644
> --- a/arch/powerpc/kernel/uprobes.c
> +++ b/arch/powerpc/kernel/uprobes.c
> @@ -111,7 +111,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(ppc_inst_read(auprobe->insn));
>  
>  	user_disable_single_step(current);
>  	return 0;
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
> index fa7f32adf029..3b8277a64b8f 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -24,17 +24,27 @@ static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
>  {
>  	int err = 0;
>  
> -	__put_user_asm(instr, patch_addr, err, "stw");
> +	__put_user_asm(ppc_inst_word(instr), patch_addr, err, "stw");
>  	if (err)
>  		return err;
>  
>  	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
>  							    "r" (exec_addr));
>  
> +	if (!ppc_inst_prefixed(instr))
> +		return 0;
> +
> +	__put_user_asm(ppc_inst_suffix(instr), patch_addr + 4, err, "stw");
> +	if (err)
> +		return err;
> +
> +	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr + 4),
> +							    "r" (exec_addr + 4));
> +
>  	return 0;
>  }
>  
> -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
> +int raw_patch_instruction(void *addr, ppc_inst instr)
>  {
>  	return __patch_instruction(addr, instr, addr);
>  }
> @@ -184,7 +194,7 @@ static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
>  
>  #endif /* CONFIG_STRICT_KERNEL_RWX */
>  
> -int patch_instruction(unsigned int *addr, unsigned int instr)
> +int patch_instruction(void *addr, ppc_inst instr)
>  {
>  	/* Make sure we aren't patching a freed init section */
>  	if (init_mem_is_free && init_section_contains(addr, 4)) {
> @@ -195,7 +205,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
>  }
>  NOKPROBE_SYMBOL(patch_instruction);
>  
> -int patch_branch(ppc_inst *addr, unsigned long target, int flags)
> +int patch_branch(void *addr, unsigned long target, int flags)
>  {
>  	return patch_instruction(addr, create_branch(addr, target, flags));
>  }
> @@ -264,7 +274,7 @@ ppc_inst create_branch(const ppc_inst *addr,
>  	return instruction;
>  }
>  
> -unsigned int create_cond_branch(const unsigned int *addr,
> +ppc_inst create_cond_branch(const void *addr,
>  				unsigned long target, int flags)
>  {
>  	ppc_inst instruction;
> @@ -344,7 +354,7 @@ static unsigned long branch_bform_target(const ppc_inst *instr)
>  	return (unsigned long)imm;
>  }
>  
> -unsigned long branch_target(const ppc_inst *instr)
> +unsigned long branch_target(const void *instr)
>  {
>  	if (instr_is_branch_iform(ppc_inst_read(instr)))
>  		return branch_iform_target(instr);
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index bae878a83fa5..ab4c71c43c8c 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1169,10 +1169,12 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
>  	unsigned long int imm;
>  	unsigned long int val, val2;
>  	unsigned int mb, me, sh;
> -	unsigned int word;
> +	unsigned int word, suffix;
>  	long ival;
>  
>  	word = ppc_inst_word(instr);
> +	suffix = ppc_inst_suffix(instr);
> +
>  	op->type = COMPUTE;
>  
>  	opcode = word >> 26;
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index ee084411f2f5..c5536e1a3356 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -110,7 +110,7 @@ struct bpt {
>  #define BP_DABR		4
>  
>  #define NBPTS	256
> -#define BPT_WORDS	2
> +#define BPT_WORDS	4
>  static struct bpt bpts[NBPTS];
>  static struct bpt dabr;
>  static struct bpt *iabr;
> @@ -118,12 +118,13 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
>  
>  #define BP_NUM(bp)	((bp) - bpts + 1)
>  
> -static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS];
> +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS] __aligned(64);
>  
>  /* Prototypes */
>  static int cmds(struct pt_regs *);
>  static int mread(unsigned long, void *, int);
>  static int mwrite(unsigned long, void *, int);
> +static int mread_instr(unsigned long, ppc_inst *);
>  static int handle_fault(struct pt_regs *);
>  static void byterev(unsigned char *, int);
>  static void memex(void);
> @@ -759,8 +760,8 @@ static int xmon_bpt(struct pt_regs *regs)
>  
>  	/* Are we at the trap at bp->instr[1] for some bp? */
>  	bp = in_breakpoint_table(regs->nip, &offset);
> -	if (bp != NULL && offset == 4) {
> -		regs->nip = bp->address + 4;
> +	if (bp != NULL && (offset == 4 || offset == 8)) {
> +		regs->nip = bp->address + offset;
>  		atomic_dec(&bp->ref_count);
>  		return 1;
>  	}
> @@ -862,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
>  	if (off >= sizeof(bpt_table))
>  		return NULL;
>  	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> -	if (bp_off != 0 && bp_off != 4)
> +	if (bp_off != 0 && bp_off != 4 && bp_off != 8)
>  		return NULL;
>  	*offp = bp_off;
>  	return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
> @@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a)
>  		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
>  			bp->address = a;
>  			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> -			patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
>  			return bp;
>  		}
>  	}
> @@ -900,7 +900,7 @@ static void insert_bpts(void)
>  	for (i = 0; i < NBPTS; ++i, ++bp) {
>  		if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
>  			continue;
> -		if (mread(bp->address, &instr, 4) != 4) {
> +		if (!mread_instr(bp->address, &instr)) {
>  			printf("Couldn't read instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
>  			bp->enabled = 0;
> @@ -913,9 +913,10 @@ static void insert_bpts(void)
>  			continue;
>  		}
>  		patch_instruction(bp->instr, instr);
> +		patch_instruction(bp->instr + ppc_inst_len(instr), PPC_INST(bpinstr));
>  		if (bp->enabled & BP_CIABR)
>  			continue;
> -		if (patch_instruction((ppc_inst *)bp->address,
> +		if (patch_instruction((void *)bp->address,
>  							PPC_INST(bpinstr)) != 0) {
>  			printf("Couldn't write instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
> @@ -950,7 +951,7 @@ static void remove_bpts(void)
>  	for (i = 0; i < NBPTS; ++i, ++bp) {
>  		if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
>  			continue;
> -		if (mread(bp->address, &instr, 4) == 4
> +		if (mread_instr(bp->address, &instr)
>  		    && ppc_inst_equal(instr, PPC_INST(bpinstr))
>  		    && patch_instruction(
>  			(ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0)
> @@ -1166,7 +1167,7 @@ static int do_step(struct pt_regs *regs)
>  	force_enable_xmon();
>  	/* check we are in 64-bit kernel mode, translation enabled */
>  	if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
> -		if (mread(regs->nip, &instr, 4) == 4) {
> +		if (mread_instr(regs->nip, &instr)) {
>  			stepped = emulate_step(regs, instr);
>  			if (stepped < 0) {
>  				printf("Couldn't single-step %s instruction\n",
> @@ -1333,7 +1334,7 @@ static long check_bp_loc(unsigned long addr)
>  		printf("Breakpoints may only be placed at kernel addresses\n");
>  		return 0;
>  	}
> -	if (!mread(addr, &instr, sizeof(instr))) {
> +	if (!mread_instr(addr, &instr)) {
>  		printf("Can't read instruction at address %lx\n", addr);
>  		return 0;
>  	}
> @@ -2126,6 +2127,21 @@ mwrite(unsigned long adrs, void *buf, int size)
>  	return n;
>  }
>  
> +static int
> +mread_instr(unsigned long adrs, ppc_inst *instr)
> +{
> +	if (setjmp(bus_error_jmp) == 0) {
> +		catch_memory_errors = 1;
> +		sync();
> +		*instr = ppc_inst_read((void *)adrs);
> +		sync();
> +		/* wait a little while to see if we get a machine check */
> +		__delay(200);
> +	}
> +	catch_memory_errors = 0;
> +	return ppc_inst_len(*instr);
> +}
> +
>  static int fault_type;
>  static int fault_except;
>  static char *fault_chars[] = { "--", "**", "##" };
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 11/16] powerpc: Enable Prefixed Instructions
  2020-03-20  5:18 ` [PATCH v4 11/16] powerpc: Enable Prefixed Instructions Jordan Niethe
@ 2020-03-23  7:02   ` Nicholas Piggin
  0 siblings, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  7:02 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:18 pm:
> From: Alistair Popple <alistair@popple.id.au>
> 
> Prefix instructions have their own FSCR bit which needs to enabled via
> a CPU feature. The kernel will save the FSCR for problem state but it
> needs to be enabled initially.
> 
> If prefixed instructions are made unavailable by the [H]FSCR, attempting
> to use them will cause a facility unavailable exception. Add "PREFIX" to
> the facility_strings[].
> 
> Currently there are no prefixed instructions that are actually emulated
> by emulate_instruction() within facility_unavailable_exception().
> However, when caused by a prefixed instructions the SRR1 PREFIXED bit is
> set. Prepare for dealing with emulated prefixed instructions by checking
> for this bit.
> 

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>

> Signed-off-by: Alistair Popple <alistair@popple.id.au>
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4:
>     - Squash "Check for prefixed instructions in
>       facility_unavailable_exception()" here
>     - Remove dt parts for now
> ---
>  arch/powerpc/include/asm/reg.h | 3 +++
>  arch/powerpc/kernel/traps.c    | 1 +
>  2 files changed, 4 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index 1aa46dff0957..c7758c2ccc5f 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -397,6 +397,7 @@
>  #define SPRN_RWMR	0x375	/* Region-Weighting Mode Register */
>  
>  /* HFSCR and FSCR bit numbers are the same */
> +#define FSCR_PREFIX_LG	13	/* Enable Prefix Instructions */
>  #define FSCR_SCV_LG	12	/* Enable System Call Vectored */
>  #define FSCR_MSGP_LG	10	/* Enable MSGP */
>  #define FSCR_TAR_LG	8	/* Enable Target Address Register */
> @@ -408,11 +409,13 @@
>  #define FSCR_VECVSX_LG	1	/* Enable VMX/VSX  */
>  #define FSCR_FP_LG	0	/* Enable Floating Point */
>  #define SPRN_FSCR	0x099	/* Facility Status & Control Register */
> +#define   FSCR_PREFIX	__MASK(FSCR_PREFIX_LG)
>  #define   FSCR_SCV	__MASK(FSCR_SCV_LG)
>  #define   FSCR_TAR	__MASK(FSCR_TAR_LG)
>  #define   FSCR_EBB	__MASK(FSCR_EBB_LG)
>  #define   FSCR_DSCR	__MASK(FSCR_DSCR_LG)
>  #define SPRN_HFSCR	0xbe	/* HV=1 Facility Status & Control Register */
> +#define   HFSCR_PREFIX	__MASK(FSCR_PREFIX_LG)
>  #define   HFSCR_MSGP	__MASK(FSCR_MSGP_LG)
>  #define   HFSCR_TAR	__MASK(FSCR_TAR_LG)
>  #define   HFSCR_EBB	__MASK(FSCR_EBB_LG)
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index 82a3438300fd..a4764b039749 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -1720,6 +1720,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
>  		[FSCR_TAR_LG] = "TAR",
>  		[FSCR_MSGP_LG] = "MSGP",
>  		[FSCR_SCV_LG] = "SCV",
> +		[FSCR_PREFIX_LG] = "PREFIX",
>  	};
>  	char *facility = "unknown";
>  	u64 value;
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 12/16] powerpc: Define new SRR1 bits for a future ISA version
  2020-03-20  5:18 ` [PATCH v4 12/16] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
@ 2020-03-23  7:03   ` Nicholas Piggin
  0 siblings, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  7:03 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:18 pm:
> Add the BOUNDARY SRR1 bit definition for when the cause of an alignment
> exception is a prefixed instruction that crosses a 64-byte boundary.
> Add the PREFIXED SRR1 bit definition for exceptions caused by prefixed
> instructions.
> 
> Bit 35 of SRR1 is called SRR1_ISI_N_OR_G. This name comes from it being
> used to indicate that an ISI was due to the access being no-exec or
> guarded. A future ISA version adds another purpose. It is also set if
> there is an access in a cache-inhibited location for prefixed
> instruction.  Rename from SRR1_ISI_N_OR_G to SRR1_ISI_N_G_OR_CIP.

Seems okay.

> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v2: Combined all the commits concerning SRR1 bits.
> ---
>  arch/powerpc/include/asm/reg.h      | 4 +++-
>  arch/powerpc/kvm/book3s_hv_nested.c | 2 +-
>  arch/powerpc/kvm/book3s_hv_rm_mmu.c | 2 +-
>  3 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
> index c7758c2ccc5f..173f33df4fab 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -762,7 +762,7 @@
>  #endif
>  
>  #define   SRR1_ISI_NOPT		0x40000000 /* ISI: Not found in hash */
> -#define   SRR1_ISI_N_OR_G	0x10000000 /* ISI: Access is no-exec or G */
> +#define   SRR1_ISI_N_G_OR_CIP	0x10000000 /* ISI: Access is no-exec or G or CI for a prefixed instruction */
>  #define   SRR1_ISI_PROT		0x08000000 /* ISI: Other protection fault */
>  #define   SRR1_WAKEMASK		0x00380000 /* reason for wakeup */
>  #define   SRR1_WAKEMASK_P8	0x003c0000 /* reason for wakeup on POWER8 and 9 */
> @@ -789,6 +789,8 @@
>  #define   SRR1_PROGADDR		0x00010000 /* SRR0 contains subsequent addr */
>  
>  #define   SRR1_MCE_MCP		0x00080000 /* Machine check signal caused interrupt */
> +#define   SRR1_BOUNDARY		0x10000000 /* Prefixed instruction crosses 64-byte boundary */
> +#define   SRR1_PREFIXED		0x20000000 /* Exception caused by prefixed instruction */
>  
>  #define SPRN_HSRR0	0x13A	/* Save/Restore Register 0 */
>  #define SPRN_HSRR1	0x13B	/* Save/Restore Register 1 */
> diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
> index dc97e5be76f6..6ab685227574 100644
> --- a/arch/powerpc/kvm/book3s_hv_nested.c
> +++ b/arch/powerpc/kvm/book3s_hv_nested.c
> @@ -1169,7 +1169,7 @@ static int kvmhv_translate_addr_nested(struct kvm_vcpu *vcpu,
>  		} else if (vcpu->arch.trap == BOOK3S_INTERRUPT_H_INST_STORAGE) {
>  			/* Can we execute? */
>  			if (!gpte_p->may_execute) {
> -				flags |= SRR1_ISI_N_OR_G;
> +				flags |= SRR1_ISI_N_G_OR_CIP;
>  				goto forward_to_l1;
>  			}
>  		} else {
> diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> index 220305454c23..b53a9f1c1a46 100644
> --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> @@ -1260,7 +1260,7 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr,
>  	status &= ~DSISR_NOHPTE;	/* DSISR_NOHPTE == SRR1_ISI_NOPT */
>  	if (!data) {
>  		if (gr & (HPTE_R_N | HPTE_R_G))
> -			return status | SRR1_ISI_N_OR_G;
> +			return status | SRR1_ISI_N_G_OR_CIP;
>  		if (!hpte_read_permission(pp, slb_v & key))
>  			return status | SRR1_ISI_PROT;
>  	} else if (status & DSISR_ISSTORE) {
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler
  2020-03-20  5:18 ` [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
@ 2020-03-23  7:05   ` Nicholas Piggin
  2020-03-23  9:35     ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  7:05 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:18 pm:
> Alignment interrupts can be caused by prefixed instructions accessing
> memory. Prefixed instructions are not permitted to cross 64-byte
> boundaries. If they do the alignment interrupt is invoked with SRR1
> BOUNDARY bit set.  If this occurs send a SIGBUS to the offending process
> if in user mode.  If in kernel mode call bad_page_fault().
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v2: - Move __get_user_instr() and __get_user_instr_inatomic() to this
> commit (previously in "powerpc sstep: Prepare to support prefixed
> instructions").
>     - Rename sufx to suffix
>     - Use a macro for calculating instruction length
> v3: Move __get_user_{instr(), instr_inatomic()} up with the other
> get_user definitions and remove nested if.
> v4: Just do the things for alignment_exception(). Other changes handled
> elsewhere.
> ---
>  arch/powerpc/kernel/traps.c | 21 ++++++++++++++++++++-
>  1 file changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index a4764b039749..cd8b3043c268 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -583,6 +583,10 @@ static inline int check_io_access(struct pt_regs *regs)
>  #define REASON_ILLEGAL		(ESR_PIL | ESR_PUO)
>  #define REASON_PRIVILEGED	ESR_PPR
>  #define REASON_TRAP		ESR_PTR
> +#define REASON_PREFIXED		0
> +#define REASON_BOUNDARY		0
> +
> +#define inst_length(reason)	4
>  
>  /* single-step stuff */
>  #define single_stepping(regs)	(current->thread.debug.dbcr0 & DBCR0_IC)
> @@ -597,6 +601,10 @@ static inline int check_io_access(struct pt_regs *regs)
>  #define REASON_ILLEGAL		SRR1_PROGILL
>  #define REASON_PRIVILEGED	SRR1_PROGPRIV
>  #define REASON_TRAP		SRR1_PROGTRAP
> +#define REASON_PREFIXED		SRR1_PREFIXED
> +#define REASON_BOUNDARY		SRR1_BOUNDARY
> +
> +#define inst_length(reason)	(((reason) & REASON_PREFIXED) ? 8 : 4)

Looks good. If you define REASON_BOUNDARY 0, then this will constant
fold away so no need to define it twice.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type
  2020-03-20  5:18 ` [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
  2020-03-23  6:58   ` Nicholas Piggin
@ 2020-03-23  7:33   ` Nicholas Piggin
  2020-03-23 23:45     ` Jordan Niethe
  2020-03-30  9:05   ` Alistair Popple
  2 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  7:33 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:18 pm:
> For powerpc64, redefine the ppc_inst type so both word and prefixed
> instructions can be represented. On powerpc32 the type will remain the
> same.  Update places which had assumed instructions to be 4 bytes long.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/include/asm/code-patching.h | 10 +--
>  arch/powerpc/include/asm/inst.h          | 90 ++++++++++++++++++++++++
>  arch/powerpc/include/asm/kprobes.h       |  2 +-
>  arch/powerpc/include/asm/sstep.h         |  4 ++
>  arch/powerpc/include/asm/uaccess.h       | 22 ++++++
>  arch/powerpc/include/asm/uprobes.h       |  2 +-
>  arch/powerpc/kernel/align.c              |  5 +-
>  arch/powerpc/kernel/hw_breakpoint.c      |  2 +-
>  arch/powerpc/kernel/kprobes.c            |  7 +-
>  arch/powerpc/kernel/optprobes.c          | 42 ++++++-----
>  arch/powerpc/kernel/optprobes_head.S     |  3 +
>  arch/powerpc/kernel/trace/ftrace.c       | 19 ++++-
>  arch/powerpc/kernel/uprobes.c            |  2 +-
>  arch/powerpc/lib/code-patching.c         | 22 ++++--
>  arch/powerpc/lib/sstep.c                 |  4 +-
>  arch/powerpc/xmon/xmon.c                 | 38 +++++++---
>  16 files changed, 221 insertions(+), 53 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
> index 68bd9db334bd..bd41e1558707 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -25,11 +25,11 @@
>  bool is_offset_in_branch_range(long offset);
>  ppc_inst create_branch(const ppc_inst *addr,
>  			   unsigned long target, int flags);
> -unsigned int create_cond_branch(const ppc_inst *addr,
> +ppc_inst create_cond_branch(const void *addr,
>  				unsigned long target, int flags);
> -int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> -int patch_instruction(ppc_inst *addr, ppc_inst instr);
> -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
> +int patch_branch(void *addr, unsigned long target, int flags);
> +int patch_instruction(void *addr, ppc_inst instr);
> +int raw_patch_instruction(void *addr, ppc_inst instr);
>  
>  static inline unsigned long patch_site_addr(s32 *site)
>  {
> @@ -60,7 +60,7 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
>  int instr_is_relative_branch(ppc_inst instr);
>  int instr_is_relative_link_branch(ppc_inst instr);
>  int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> -unsigned long branch_target(const ppc_inst *instr);
> +unsigned long branch_target(const void *instr);
>  ppc_inst translate_branch(const ppc_inst *dest,
>  			      const ppc_inst *src);
>  extern bool is_conditional_branch(ppc_inst instr);
> diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> index 7c8596ee411e..1a40b0a71128 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -6,6 +6,95 @@
>   * Instruction data type for POWER
>   */
>  
> +#ifdef __powerpc64__
> +
> +typedef struct ppc_inst {
> +	union {
> +		struct {
> +			u32 word;
> +			u32 pad;
> +		} __packed;
> +		struct {
> +			u32 prefix;
> +			u32 suffix;
> +		} __packed;
> +	};
> +} ppc_inst;
> +
> +#define PPC_INST(x) ((ppc_inst) { .word = (x), .pad = 0 })
> +#define PPC_INST_PREFIXED(x, y) ((ppc_inst) { .prefix = (x), .suffix = (y) })
> +
> +static inline int ppc_inst_opcode(ppc_inst x)
> +{
> +	return x.word >> 26;
> +}
> +
> +static inline bool ppc_inst_prefixed(ppc_inst x) {
> +	return ppc_inst_opcode(x) == 1;
> +}
> +
> +static inline int ppc_inst_len(ppc_inst x)
> +{
> +	if (ppc_inst_prefixed(x))
> +		return 8;
> +	else
> +		return 4;
> +}
> +
> +static inline u32 ppc_inst_word(ppc_inst x)
> +{
> +	return x.word;
> +}

I guess a concern could be that code using ppc_inst_word could now get a 
prefix unexpectedly and not handle it properly. The reason it should
generally be okay is that prefix won't match any existing valid
instruction words, so callers won't match or think it's an unknown
instruction. Am I right? Possibly a small comment?

> +
> +static inline u32 ppc_inst_prefix(ppc_inst x)
> +{
> +	return x.prefix;
> +}
> +
> +static inline u32 ppc_inst_suffix(ppc_inst x)
> +{
> +	return x.suffix;
> +}
> +
> +
> +static inline ppc_inst ppc_inst_read(const void *ptr)
> +{
> +	ppc_inst inst;
> +	inst.word = *(u32 *)ptr;
> +	if (ppc_inst_prefixed(inst))
> +		inst.suffix = *((u32 *)ptr + 1);
> +	else
> +		inst.pad = 0;

I'm a bit against using partially constructed opaque type for things 
like this, even if it is in the code that knows about the type. We
could modify ppc_inst_prefixed() to assert that pad is equal to zero
(or some poisoned value) if it's not prefixed. Or do some validation
on the suffix if it is.


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

I guess a variable length memcmp will make terrible code, so you're
requiring pad to equal 0 to match non-prefixed. Fine.

> +
> +static inline bool ppc_inst_null(ppc_inst x)
> +{
> +	return x.word == 0 && x.pad == 0;
> +}

In this case you shouldn't need x.pad == 0. If x.word == 0, then
WARN_ON_ONCE(x.pad != 0) ?

>  	if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
>  		/* We don't handle PPC little-endian any more... */
>  		if (cpu_has_feature(CPU_FTR_PPC_LE))
>  			return -EIO;
> -		instr = PPC_INST(swab32(ppc_inst_word(instr)));
> +		instr = PPC_INST_PREFIXED(swab32(ppc_inst_word(instr)),
> +					  swab32(ppc_inst_suffix(instr)));

Ugly, don't suppose you'd bother to do a ppc_inst_bswap function for 
this one case?

[snip probes stuff]

> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
> index fa7f32adf029..3b8277a64b8f 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -24,17 +24,27 @@ static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
>  {
>  	int err = 0;
>  
> -	__put_user_asm(instr, patch_addr, err, "stw");
> +	__put_user_asm(ppc_inst_word(instr), patch_addr, err, "stw");
>  	if (err)
>  		return err;
>  
>  	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
>  							    "r" (exec_addr));
>  
> +	if (!ppc_inst_prefixed(instr))
> +		return 0;
> +
> +	__put_user_asm(ppc_inst_suffix(instr), patch_addr + 4, err, "stw");
> +	if (err)
> +		return err;
> +
> +	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr + 4),
> +							    "r" (exec_addr + 4));

Although there's proably no real performance or atomicity issues here,
I'd be pleased if we could do a case for prefixed and a case for non
prefixed, and store the non-prefixed with "std". Just for the principle
of not having half-written instructions in the image.

You could skip the dcbst and icbi for the second address if you happen
to know this future CPU does not store prefix insns across a CL
boundary. But probably not necessary to make that assumption in non
perf critical code here, so I'd leave it as you have.

> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index ee084411f2f5..c5536e1a3356 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -110,7 +110,7 @@ struct bpt {
>  #define BP_DABR		4
>  
>  #define NBPTS	256
> -#define BPT_WORDS	2
> +#define BPT_WORDS	4

(2 * sizeof(ppc_inst) / sizeof(u32)) ?

>  static struct bpt bpts[NBPTS];
>  static struct bpt dabr;
>  static struct bpt *iabr;
> @@ -118,12 +118,13 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
>  
>  #define BP_NUM(bp)	((bp) - bpts + 1)
>  
> -static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS];
> +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS] __aligned(64);

Should have a define somewhere for this magical 64.

>  /* Prototypes */
>  static int cmds(struct pt_regs *);
>  static int mread(unsigned long, void *, int);
>  static int mwrite(unsigned long, void *, int);
> +static int mread_instr(unsigned long, ppc_inst *);

In some cases you've addd helpers like this as separate patches,
others you've bundled them together. NBD but I liked the prep patches
which then made the more important changes easier to see.

> @@ -759,8 +760,8 @@ static int xmon_bpt(struct pt_regs *regs)
>  
>  	/* Are we at the trap at bp->instr[1] for some bp? */
>  	bp = in_breakpoint_table(regs->nip, &offset);
> -	if (bp != NULL && offset == 4) {
> -		regs->nip = bp->address + 4;
> +	if (bp != NULL && (offset == 4 || offset == 8)) {
> +		regs->nip = bp->address + offset;
>  		atomic_dec(&bp->ref_count);
>  		return 1;
>  	}
> @@ -862,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
>  	if (off >= sizeof(bpt_table))
>  		return NULL;
>  	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> -	if (bp_off != 0 && bp_off != 4)
> +	if (bp_off != 0 && bp_off != 4 && bp_off != 8)
>  		return NULL;
>  	*offp = bp_off;
>  	return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
> @@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a)
>  		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
>  			bp->address = a;
>  			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> -			patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
>  			return bp;
>  		}
>  	}

Why is this okay to remove?

Thanks,
Nick


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 09/16] powerpc: Use a function for reading instructions
  2020-03-20  5:18 ` [PATCH v4 09/16] powerpc: Use a function for reading instructions Jordan Niethe
@ 2020-03-23  8:00   ` Nicholas Piggin
  2020-03-23  8:43     ` Balamuruhan S
  2020-03-23 10:09     ` Jordan Niethe
  0 siblings, 2 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  8:00 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, bala24

Jordan Niethe's on March 20, 2020 3:18 pm:
> Prefixed instructions will mean there are instructions of different
> length. As a result dereferencing a pointer to an instruction will not
> necessarily give the desired result. Introduce a function for reading
> instructions from memory into the instruction data type.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/include/asm/uprobes.h |  4 ++--
>  arch/powerpc/kernel/kprobes.c      |  8 ++++----
>  arch/powerpc/kernel/mce_power.c    |  2 +-
>  arch/powerpc/kernel/optprobes.c    |  6 +++---
>  arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++-----------
>  arch/powerpc/kernel/uprobes.c      |  2 +-
>  arch/powerpc/lib/code-patching.c   | 22 ++++++++++----------
>  arch/powerpc/lib/feature-fixups.c  |  6 +++---
>  arch/powerpc/xmon/xmon.c           |  6 +++---
>  9 files changed, 49 insertions(+), 40 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
> index 2bbdf27d09b5..fff3c5fc90b5 100644
> --- a/arch/powerpc/include/asm/uprobes.h
> +++ b/arch/powerpc/include/asm/uprobes.h
> @@ -23,8 +23,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
>  
>  struct arch_uprobe {
>  	union {
> -		u32	insn;
> -		u32	ixol;
> +		u8	insn[MAX_UINSN_BYTES];
> +		u8	ixol[MAX_UINSN_BYTES];
>  	};
>  };

Hmm. I wonder if this should be a different patch. Not sure if raw
bytes is a good idea here. ppc probes also has a ppc_opcode_t, maybe
could be replaced with ppc_insn_t and used here instead?

Also can't find where you define ppc_inst_read.

> diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
> index 7614a9f537fd..ad451205f268 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -41,6 +41,12 @@
>  #define	NUM_FTRACE_TRAMPS	8
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
>  
> +static long
> +read_inst(ppc_inst *inst, const void *src)
> +{
> +	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> +}

Humbly suggest probe_kernel_inst_read.

Thanks,
Nick


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 09/16] powerpc: Use a function for reading instructions
  2020-03-23  8:00   ` Nicholas Piggin
@ 2020-03-23  8:43     ` Balamuruhan S
  2020-03-23 10:09     ` Jordan Niethe
  1 sibling, 0 replies; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23  8:43 UTC (permalink / raw)
  To: Nicholas Piggin, Jordan Niethe, linuxppc-dev; +Cc: alistair, dja

On Mon, 2020-03-23 at 18:00 +1000, Nicholas Piggin wrote:
> Jordan Niethe's on March 20, 2020 3:18 pm:
> > Prefixed instructions will mean there are instructions of different
> > length. As a result dereferencing a pointer to an instruction will not
> > necessarily give the desired result. Introduce a function for reading
> > instructions from memory into the instruction data type.
> > 
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v4: New to series
> > ---
> >  arch/powerpc/include/asm/uprobes.h |  4 ++--
> >  arch/powerpc/kernel/kprobes.c      |  8 ++++----
> >  arch/powerpc/kernel/mce_power.c    |  2 +-
> >  arch/powerpc/kernel/optprobes.c    |  6 +++---
> >  arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++-----------
> >  arch/powerpc/kernel/uprobes.c      |  2 +-
> >  arch/powerpc/lib/code-patching.c   | 22 ++++++++++----------
> >  arch/powerpc/lib/feature-fixups.c  |  6 +++---
> >  arch/powerpc/xmon/xmon.c           |  6 +++---
> >  9 files changed, 49 insertions(+), 40 deletions(-)
> > 
> > diff --git a/arch/powerpc/include/asm/uprobes.h
> > b/arch/powerpc/include/asm/uprobes.h
> > index 2bbdf27d09b5..fff3c5fc90b5 100644
> > --- a/arch/powerpc/include/asm/uprobes.h
> > +++ b/arch/powerpc/include/asm/uprobes.h
> > @@ -23,8 +23,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
> >  
> >  struct arch_uprobe {
> >  	union {
> > -		u32	insn;
> > -		u32	ixol;
> > +		u8	insn[MAX_UINSN_BYTES];
> > +		u8	ixol[MAX_UINSN_BYTES];
> >  	};
> >  };
> 
> Hmm. I wonder if this should be a different patch. Not sure if raw
> bytes is a good idea here. ppc probes also has a ppc_opcode_t, maybe
> could be replaced with ppc_insn_t and used here instead?
> 
> Also can't find where you define ppc_inst_read.

Nick, ppc_inst_read and macro PPC_INST you have asked in patch 4 are defined in
asm/inst.h with patch 3 (powerpc: Use a datatype for instructions)

-- Bala
> 
> > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > b/arch/powerpc/kernel/trace/ftrace.c
> > index 7614a9f537fd..ad451205f268 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -41,6 +41,12 @@
> >  #define	NUM_FTRACE_TRAMPS	8
> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> >  
> > +static long
> > +read_inst(ppc_inst *inst, const void *src)
> > +{
> > +	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> > +}
> 
> Humbly suggest probe_kernel_inst_read.
> 
> Thanks,
> Nick
> 


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 15/16] powerpc sstep: Add support for prefixed load/stores
  2020-03-20  5:18 ` [PATCH v4 15/16] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
@ 2020-03-23  8:54   ` Balamuruhan S
  0 siblings, 0 replies; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23  8:54 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Fri, 2020-03-20 at 16:18 +1100, Jordan Niethe wrote:
> This adds emulation support for the following prefixed integer
> load/stores:
>   * Prefixed Load Byte and Zero (plbz)
>   * Prefixed Load Halfword and Zero (plhz)
>   * Prefixed Load Halfword Algebraic (plha)
>   * Prefixed Load Word and Zero (plwz)
>   * Prefixed Load Word Algebraic (plwa)
>   * Prefixed Load Doubleword (pld)
>   * Prefixed Store Byte (pstb)
>   * Prefixed Store Halfword (psth)
>   * Prefixed Store Word (pstw)
>   * Prefixed Store Doubleword (pstd)
>   * Prefixed Load Quadword (plq)
>   * Prefixed Store Quadword (pstq)
> 
> the follow prefixed floating-point load/stores:
>   * Prefixed Load Floating-Point Single (plfs)
>   * Prefixed Load Floating-Point Double (plfd)
>   * Prefixed Store Floating-Point Single (pstfs)
>   * Prefixed Store Floating-Point Double (pstfd)
> 
> and for the following prefixed VSX load/stores:
>   * Prefixed Load VSX Scalar Doubleword (plxsd)
>   * Prefixed Load VSX Scalar Single-Precision (plxssp)
>   * Prefixed Load VSX Vector [0|1]  (plxv, plxv0, plxv1)
>   * Prefixed Store VSX Scalar Doubleword (pstxsd)
>   * Prefixed Store VSX Scalar Single-Precision (pstxssp)
>   * Prefixed Store VSX Vector [0|1] (pstxv, pstxv0, pstxv1)
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>

LGTM,

Reviewed-by: Balamuruhan S <bala24@linux.ibm.com>

> ---
> v2: - Combine all load/store patches
>     - Fix the name of Type 01 instructions
>     - Remove sign extension flag from pstd/pld
>     - Rename sufx -> suffix
> v3: - Move prefixed loads and stores into the switch statement
> ---
>  arch/powerpc/lib/sstep.c | 159 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 159 insertions(+)
> 
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index ab4c71c43c8c..daef70eb8e22 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -187,6 +187,44 @@ static nokprobe_inline unsigned long xform_ea(unsigned
> int instr,
>  	return ea;
>  }
>  
> +/*
> + * Calculate effective address for a MLS:D-form / 8LS:D-form
> + * prefixed instruction
> + */
> +static nokprobe_inline unsigned long mlsd_8lsd_ea(unsigned int instr,
> +						  unsigned int suffix,
> +						  const struct pt_regs *regs)
> +{
> +	int ra, prefix_r;
> +	unsigned int  dd;
> +	unsigned long ea, d0, d1, d;
> +
> +	prefix_r = instr & (1ul << 20);
> +	ra = (suffix >> 16) & 0x1f;
> +
> +	d0 = instr & 0x3ffff;
> +	d1 = suffix & 0xffff;
> +	d = (d0 << 16) | d1;
> +
> +	/*
> +	 * sign extend a 34 bit number
> +	 */
> +	dd = (unsigned int)(d >> 2);
> +	ea = (signed int)dd;
> +	ea = (ea << 2) | (d & 0x3);
> +
> +	if (!prefix_r && ra)
> +		ea += regs->gpr[ra];
> +	else if (!prefix_r && !ra)
> +		; /* Leave ea as is */
> +	else if (prefix_r && !ra)
> +		ea += regs->nip;
> +	else if (prefix_r && ra)
> +		; /* Invalid form. Should already be checked for by caller! */
> +
> +	return ea;
> +}
> +
>  /*
>   * Return the largest power of 2, not greater than sizeof(unsigned long),
>   * such that x is a multiple of it.
> @@ -1166,6 +1204,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		  ppc_inst instr)
>  {
>  	unsigned int opcode, ra, rb, rc, rd, spr, u;
> +	unsigned int suffixopcode, prefixtype, prefix_r;
>  	unsigned long int imm;
>  	unsigned long int val, val2;
>  	unsigned int mb, me, sh;
> @@ -2652,6 +2691,126 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			break;
>  		}
>  		break;
> +	case 1: /* Prefixed instructions */
> +		prefix_r = word & (1ul << 20);
> +		ra = (suffix >> 16) & 0x1f;
> +		op->update_reg = ra;
> +		rd = (suffix >> 21) & 0x1f;
> +		op->reg = rd;
> +		op->val = regs->gpr[rd];
> +
> +		suffixopcode = suffix >> 26;
> +		prefixtype = (word >> 24) & 0x3;
> +		switch (prefixtype) {
> +		case 0: /* Type 00  Eight-Byte Load/Store */
> +			if (prefix_r && ra)
> +				break;
> +			op->ea = mlsd_8lsd_ea(word, suffix, regs);
> +			switch (suffixopcode) {
> +			case 41:	/* plwa */
> +				op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 4);
> +				break;
> +			case 42:        /* plxsd */
> +				op->reg = rd + 32;
> +				op->type = MKOP(LOAD_VSX, PREFIXED, 8);
> +				op->element_size = 8;
> +				op->vsx_flags = VSX_CHECK_VEC;
> +				break;
> +			case 43:	/* plxssp */
> +				op->reg = rd + 32;
> +				op->type = MKOP(LOAD_VSX, PREFIXED, 4);
> +				op->element_size = 8;
> +				op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
> +				break;
> +			case 46:	/* pstxsd */
> +				op->reg = rd + 32;
> +				op->type = MKOP(STORE_VSX, PREFIXED, 8);
> +				op->element_size = 8;
> +				op->vsx_flags = VSX_CHECK_VEC;
> +				break;
> +			case 47:	/* pstxssp */
> +				op->reg = rd + 32;
> +				op->type = MKOP(STORE_VSX, PREFIXED, 4);
> +				op->element_size = 8;
> +				op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
> +				break;
> +			case 51:	/* plxv1 */
> +				op->reg += 32;
> +
> +				/* fallthru */
> +			case 50:	/* plxv0 */
> +				op->type = MKOP(LOAD_VSX, PREFIXED, 16);
> +				op->element_size = 16;
> +				op->vsx_flags = VSX_CHECK_VEC;
> +				break;
> +			case 55:	/* pstxv1 */
> +				op->reg = rd + 32;
> +
> +				/* fallthru */
> +			case 54:	/* pstxv0 */
> +				op->type = MKOP(STORE_VSX, PREFIXED, 16);
> +				op->element_size = 16;
> +				op->vsx_flags = VSX_CHECK_VEC;
> +				break;
> +			case 56:        /* plq */
> +				op->type = MKOP(LOAD, PREFIXED, 16);
> +				break;
> +			case 57:	/* pld */
> +				op->type = MKOP(LOAD, PREFIXED, 8);
> +				break;
> +			case 60:        /* stq */
> +				op->type = MKOP(STORE, PREFIXED, 16);
> +				break;
> +			case 61:	/* pstd */
> +				op->type = MKOP(STORE, PREFIXED, 8);
> +				break;
> +			}
> +			break;
> +		case 1: /* Type 01 Eight-Byte Register-to-Register */
> +			break;
> +		case 2: /* Type 10 Modified Load/Store */
> +			if (prefix_r && ra)
> +				break;
> +			op->ea = mlsd_8lsd_ea(word, suffix, regs);
> +			switch (suffixopcode) {
> +			case 32:	/* plwz */
> +				op->type = MKOP(LOAD, PREFIXED, 4);
> +				break;
> +			case 34:	/* plbz */
> +				op->type = MKOP(LOAD, PREFIXED, 1);
> +				break;
> +			case 36:	/* pstw */
> +				op->type = MKOP(STORE, PREFIXED, 4);
> +				break;
> +			case 38:	/* pstb */
> +				op->type = MKOP(STORE, PREFIXED, 1);
> +				break;
> +			case 40:	/* plhz */
> +				op->type = MKOP(LOAD, PREFIXED, 2);
> +				break;
> +			case 42:	/* plha */
> +				op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 2);
> +				break;
> +			case 44:	/* psth */
> +				op->type = MKOP(STORE, PREFIXED, 2);
> +				break;
> +			case 48:        /* plfs */
> +				op->type = MKOP(LOAD_FP, PREFIXED | FPCONV, 4);
> +				break;
> +			case 50:        /* plfd */
> +				op->type = MKOP(LOAD_FP, PREFIXED, 8);
> +				break;
> +			case 52:        /* pstfs */
> +				op->type = MKOP(STORE_FP, PREFIXED | FPCONV,
> 4);
> +				break;
> +			case 54:        /* pstfd */
> +				op->type = MKOP(STORE_FP, PREFIXED, 8);
> +				break;
> +			}
> +			break;
> +		case 3: /* Type 11 Modified Register-to-Register */
> +			break;
> +		}
>  #endif /* __powerpc64__ */
>  
>  	}


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 00/16] Initial Prefixed Instruction support
  2020-03-23  6:18 ` [PATCH v4 00/16] Initial Prefixed Instruction support Nicholas Piggin
@ 2020-03-23  9:25   ` Jordan Niethe
  2020-03-23 10:17     ` Nicholas Piggin
  0 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:25 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 5:22 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:17 pm:
> > A future revision of the ISA will introduce prefixed instructions. A
> > prefixed instruction is composed of a 4-byte prefix followed by a
> > 4-byte suffix.
> >
> > All prefixes have the major opcode 1. A prefix will never be a valid
> > word instruction. A suffix may be an existing word instruction or a
> > new instruction.
> >
> > This series enables prefixed instructions and extends the instruction
> > emulation to support them. Then the places where prefixed instructions
> > might need to be emulated are updated.
> >
> > The series is based on top of:
> > https://patchwork.ozlabs.org/patch/1232619/ as this will effect
> > kprobes.
> >
> > v4 is based on feedback from Nick Piggins, Christophe Leroy and Daniel Axtens.
> > The major changes:
> >     - Move xmon breakpoints from data section to text section
> >     - Introduce a data type for instructions on powerpc
>
> Thanks for doing this, looks like a lot of work, I hope it works out :)
>
Yes it did end up touching a lot of places. I started thinking that
that maybe it would be simpler to just use a u64 instead of the struct
for  instructions.
If we always keep the word instruction / prefix in the lower bytes,
all of the current masking should still work and we can use operators
again instead of ppc_inst_equal(), etc.
It also makes printing easier. We could just #define INST_FMT %llx or
#define INST_FMT %x on powerpc32 and use that for printing out
instructions.
> Thanks,
> Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 02/16] xmon: Move out-of-line instructions to text section
  2020-03-23  6:05   ` Balamuruhan S
@ 2020-03-23  9:26     ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:26 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, Nicholas Piggin, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 5:05 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> > To execute an instruction out of line after a breakpoint, the NIP is
> > set
> > to the address of struct bpt::instr. Here a copy of the instruction
> > that
> > was replaced with a breakpoint is kept, along with a trap so normal
> > flow
> > can be resumed after XOLing. The struct bpt's are located within the
> > data section. This is problematic as the data section may be marked
> > as
> > no execute.
> >
> > Instead of each struct bpt holding the instructions to be XOL'd, make
> > a
> > new array, bpt_table[], with enough space to hold instructions for
> > the
> > number of supported breakpoints. Place this array in the text
> > section.
> > Make struct bpt::instr a pointer to the instructions in bpt_table[]
> > associated with that breakpoint. This association is a simple
> > mapping:
> > bpts[n] -> bpt_table[n * words per breakpoint].
>
> Can we have it in separate commits ?
>         * introduce the array bpt_table[] and make struct bpt::instr a
>                 pointer to the instructions in bpt_table[].
>         * place the array in text section.
Yeah I can split it if that would be clearer.
>
> > Currently we only need
> > the copied instruction followed by a trap, so 2 words per breakpoint.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v4: New to series
> > ---
> >  arch/powerpc/kernel/vmlinux.lds.S |  2 +-
> >  arch/powerpc/xmon/xmon.c          | 22 +++++++++++++---------
> >  2 files changed, 14 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/vmlinux.lds.S
> > b/arch/powerpc/kernel/vmlinux.lds.S
> > index b4c89a1acebb..e90845b8c300 100644
> > --- a/arch/powerpc/kernel/vmlinux.lds.S
> > +++ b/arch/powerpc/kernel/vmlinux.lds.S
> > @@ -86,7 +86,7 @@ SECTIONS
> >               ALIGN_FUNCTION();
> >  #endif
> >               /* careful! __ftr_alt_* sections need to be close to
> > .text */
> > -             *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup
> > __ftr_alt_* .ref.text);
> > +             *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup
> > __ftr_alt_* .ref.text .text.xmon_bpts);
> >  #ifdef CONFIG_PPC64
> >               *(.tramp.ftrace.text);
> >  #endif
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index 02e3bd62cab4..7875d1a37770 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -97,7 +97,7 @@ static long *xmon_fault_jmp[NR_CPUS];
> >  /* Breakpoint stuff */
> >  struct bpt {
> >       unsigned long   address;
> > -     unsigned int    instr[2];
> > +     unsigned int    *instr;
> >       atomic_t        ref_count;
> >       int             enabled;
> >       unsigned long   pad;
> > @@ -109,6 +109,7 @@ struct bpt {
> >  #define BP_DABR              4
> >
> >  #define NBPTS        256
> > +#define BPT_WORDS    2
> >  static struct bpt bpts[NBPTS];
> >  static struct bpt dabr;
> >  static struct bpt *iabr;
> > @@ -116,6 +117,8 @@ static unsigned bpinstr = 0x7fe00008;     /* trap
> > */
> >
> >  #define BP_NUM(bp)   ((bp) - bpts + 1)
> >
> > +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS *
> > BPT_WORDS];
> > +
> >  /* Prototypes */
> >  static int cmds(struct pt_regs *);
> >  static int mread(unsigned long, void *, int);
> > @@ -852,16 +855,16 @@ static struct bpt *at_breakpoint(unsigned long
> > pc)
> >  static struct bpt *in_breakpoint_table(unsigned long nip, unsigned
> > long *offp)
> >  {
> >       unsigned long off;
> > +     unsigned long bp_off;
> >
> > -     off = nip - (unsigned long) bpts;
> > -     if (off >= sizeof(bpts))
> > +     off = nip - (unsigned long) bpt_table;
> > +     if (off >= sizeof(bpt_table))
> >               return NULL;
> > -     off %= sizeof(struct bpt);
> > -     if (off != offsetof(struct bpt, instr[0])
> > -         && off != offsetof(struct bpt, instr[1]))
> > +     bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> > +     if (bp_off != 0 && bp_off != 4)
> >               return NULL;
> > -     *offp = off - offsetof(struct bpt, instr[0]);
> > -     return (struct bpt *) (nip - off);
> > +     *offp = bp_off;
> > +     return bpts + ((off - bp_off) / (sizeof(unsigned int) *
> > BPT_WORDS));
>
> `(off - bp_off) / (sizeof(unsigned int) * BPT_WORDS)` seems to be the
> actual breakpoint offset. Can we have something like,
>
> #define NBPTS  256
> #define BPT_WORDS      2
> #define BPT_WORDS_SIZE (sizeof(unsigned int) * BPT_WORDS)
> #define BPT_OFFSET(off, bp_word_off) ((off - bp_word_off) / \                                   BPT_WORDS_SIZE)
> ;
> :::
> :::
> :::
> bp_word_off = off % BPT_WORDS_SIZE;
> if (bp_word_off != 0 && bp_word_off != 4)
>         return NULL;
> *offp = bp_word_off;
> return bpts + BPT_OFFSET(off, bp_word_off);
I do agree this is not very clear int terms of the calculations I
don't really want to introduce some macros to be used just once. I
will try to think of a way to make the calculations look more clear.
>
> -- Bala
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-23  6:23   ` Nicholas Piggin
@ 2020-03-23  9:28     ` Jordan Niethe
  2020-03-23  9:51       ` Nicholas Piggin
  0 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:28 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 5:27 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:17 pm:
> > Currently unsigned ints are used to represent instructions on powerpc.
> > This has worked well as instructions have always been 4 byte words.
> > However, a future ISA version will introduce some changes to
> > instructions that mean this scheme will no longer work as well. This
> > change is Prefixed Instructions. A prefixed instruction is made up of a
> > word prefix followed by a word suffix to make an 8 byte double word
> > instruction. No matter the endianess of the system the prefix always
> > comes first. Prefixed instructions are only planned for powerpc64.
> >
> > Introduce a ppc_inst type to represent both prefixed and word
> > instructions on powerpc64 while keeping it possible to exclusively have
> > word instructions on powerpc32, A latter patch will expand the type to
> > include prefixed instructions but for now just typedef it to a u32.
> >
> > Later patches will introduce helper functions and macros for
> > manipulating the instructions so that powerpc64 and powerpc32 might
> > maintain separate type definitions.
>
> ppc_inst_t I would slightly prefer for a typedef like this.
Are _t types meant to be reserved?
>
> Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s
  2020-03-23  6:26   ` Nicholas Piggin
@ 2020-03-23  9:29     ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:29 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 5:30 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:17 pm:
> > In preparation for instructions having a more complex data type start
> > using a macro, PPC_INST(), for making an instruction out of a u32.
> > Currently this does nothing, but it will allow for creating a data type
> > that can represent prefixed instructions.
>
> Where is the macro? And, can it be a static inline (and lowercase)
> instead? No big deal if not.
It is in [PATCH v4 03/16] powerpc: Use a datatype for instructions inst.h.
It can be static inline and lower case, I will change that.
>
> Thanks,
> Nick
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 05/16] powerpc: Use a function for masking instructions
  2020-03-23  6:37   ` Nicholas Piggin
@ 2020-03-23  9:31     ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:31 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 5:40 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:17 pm:
> > In preparation for using an instruction data type that can not be used
> > directly with the '&' operator, use a function to mask instructions.
>
> Hmm. ppc_inst_mask isn't such a good interface I think. It takes a
> ppc_inst and a mask, you would expect it to return a ppc_inst, probably
> with some part of its value anded with your mask value but not entirely
> clear.
>
> I would have a ppc_inst_val that is a more mechanical replacement and
> lets you do more things with it, although I like the other helpers you
> add later. Oh you've added ppc_inst_word further down. Why not use that
> here intead of ppc_inst_mask()?
ppc_inst_word() was what I started using first, but I started seeing a
whole lot of them immediately being &'d so I made ppc_inst_mask().
The ppc_inst_word() patch can come first, and I will just get rid of
the ppc_inst_mask() function - it is not very clear.
>
> Thanks,
> Nick
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality
  2020-03-23  6:43   ` Nicholas Piggin
@ 2020-03-23  9:31     ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:31 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 5:46 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:18 pm:
> > In preparation for an instruction data type that can not be directly
> > used with the '==' operator use functions for checking equality and
> > nullity.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> >  arch/powerpc/kernel/optprobes.c      |  2 +-
> >  arch/powerpc/kernel/trace/ftrace.c   | 33 +++++++++++++++-------------
> >  arch/powerpc/lib/code-patching.c     | 16 +++++++-------
> >  arch/powerpc/lib/feature-fixups.c    |  2 +-
> >  arch/powerpc/lib/test_emulate_step.c |  4 ++--
> >  arch/powerpc/xmon/xmon.c             |  4 ++--
> >  6 files changed, 32 insertions(+), 29 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> > index 1025a7a3b3a8..6027425a85f2 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -259,7 +259,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
> >                               (unsigned long)emulate_step_addr,
> >                               BRANCH_SET_LINK);
> >
> > -     if (!branch_op_callback || !branch_emulate_step)
> > +     if (ppc_inst_null(branch_op_callback) || ppc_inst_null(branch_emulate_step))
>
> Is an instruction null, or zeroes?
ppc_inst_zero() would probably be clearer.
>
> Oh, most of this comes from create_branch and things. Hmm, would rather
> see those functions modified to take a &insn and return an int err.
Good idea.
>
>
> > @@ -437,7 +438,7 @@ int ftrace_make_nop(struct module *mod,
> >        * then we had to use a trampoline to make the call.
> >        * Otherwise just update the call site.
> >        */
> > -     if (test_24bit_addr(ip, addr)) {
> > +     if (!ppc_inst_null(test_24bit_addr(ip, addr))) {
> >               /* within range */
> >               old = ftrace_call_replace(ip, addr, 1);
> >               new = PPC_INST(PPC_INST_NOP);
>
> test_24bit_addr shouldn't be passing a ppc_inst back, but a bool.
True.
>
> Thanks,
> Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code
  2020-03-23  6:54   ` Balamuruhan S
@ 2020-03-23  9:35     ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:35 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, Nicholas Piggin, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 5:54 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> > In preparation for using a data type for instructions that can not be
> > directly used with the '>>' operator use a function for getting the op
> > code of an instruction.
>
> we need to adopt this in sstep.c and vecemu.c
Thank you, I had forgotten about vecemu.c.
>
> -- Bala
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v4: New to series
> > ---
> >  arch/powerpc/kernel/align.c      | 4 ++--
> >  arch/powerpc/lib/code-patching.c | 4 ++--
> >  2 files changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > index 38542fffa179..77c49dfdc1b4 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -313,8 +313,8 @@ int fix_alignment(struct pt_regs *regs)
> >       }
> >
> >  #ifdef CONFIG_SPE
> > -     if ((instr >> 26) == 0x4) {
> > -             int reg = (instr >> 21) & 0x1f;
> > +     if (ppc_inst_opcode(instr) == 0x4) {
> > +             int reg = (ppc_inst_word(instr) >> 21) & 0x1f;
> >               PPC_WARN_ALIGNMENT(spe, regs);
> >               return emulate_spe(regs, reg, instr);
> >       }
> > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > patching.c
> > index e2ba23fd6f4d..04a303c059e2 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -228,7 +228,7 @@ bool is_offset_in_branch_range(long offset)
> >   */
> >  bool is_conditional_branch(ppc_inst instr)
> >  {
> > -     unsigned int opcode = instr >> 26;
> > +     unsigned int opcode = ppc_inst_opcode(instr);
> >
> >       if (opcode == 16)       /* bc, bca, bcl, bcla */
> >               return true;
> > @@ -286,7 +286,7 @@ unsigned int create_cond_branch(const unsigned int *addr,
> >
> >  static unsigned int branch_opcode(ppc_inst instr)
> >  {
> > -     return (instr >> 26) & 0x3F;
> > +     return ppc_inst_opcode(instr) & 0x3F;
> >  }
> >
> >  static int instr_is_branch_iform(ppc_inst instr)
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler
  2020-03-23  7:05   ` Nicholas Piggin
@ 2020-03-23  9:35     ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23  9:35 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 6:09 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:18 pm:
> > Alignment interrupts can be caused by prefixed instructions accessing
> > memory. Prefixed instructions are not permitted to cross 64-byte
> > boundaries. If they do the alignment interrupt is invoked with SRR1
> > BOUNDARY bit set.  If this occurs send a SIGBUS to the offending process
> > if in user mode.  If in kernel mode call bad_page_fault().
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v2: - Move __get_user_instr() and __get_user_instr_inatomic() to this
> > commit (previously in "powerpc sstep: Prepare to support prefixed
> > instructions").
> >     - Rename sufx to suffix
> >     - Use a macro for calculating instruction length
> > v3: Move __get_user_{instr(), instr_inatomic()} up with the other
> > get_user definitions and remove nested if.
> > v4: Just do the things for alignment_exception(). Other changes handled
> > elsewhere.
> > ---
> >  arch/powerpc/kernel/traps.c | 21 ++++++++++++++++++++-
> >  1 file changed, 20 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> > index a4764b039749..cd8b3043c268 100644
> > --- a/arch/powerpc/kernel/traps.c
> > +++ b/arch/powerpc/kernel/traps.c
> > @@ -583,6 +583,10 @@ static inline int check_io_access(struct pt_regs *regs)
> >  #define REASON_ILLEGAL               (ESR_PIL | ESR_PUO)
> >  #define REASON_PRIVILEGED    ESR_PPR
> >  #define REASON_TRAP          ESR_PTR
> > +#define REASON_PREFIXED              0
> > +#define REASON_BOUNDARY              0
> > +
> > +#define inst_length(reason)  4
> >
> >  /* single-step stuff */
> >  #define single_stepping(regs)        (current->thread.debug.dbcr0 & DBCR0_IC)
> > @@ -597,6 +601,10 @@ static inline int check_io_access(struct pt_regs *regs)
> >  #define REASON_ILLEGAL               SRR1_PROGILL
> >  #define REASON_PRIVILEGED    SRR1_PROGPRIV
> >  #define REASON_TRAP          SRR1_PROGTRAP
> > +#define REASON_PREFIXED              SRR1_PREFIXED
> > +#define REASON_BOUNDARY              SRR1_BOUNDARY
> > +
> > +#define inst_length(reason)  (((reason) & REASON_PREFIXED) ? 8 : 4)
>
> Looks good. If you define REASON_BOUNDARY 0, then this will constant
> fold away so no need to define it twice.
Good point.
>
> Thanks,
> Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-23  9:28     ` Jordan Niethe
@ 2020-03-23  9:51       ` Nicholas Piggin
  2020-03-24  2:58         ` Michael Ellerman
  0 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23  9:51 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

Jordan Niethe's on March 23, 2020 7:28 pm:
> On Mon, Mar 23, 2020 at 5:27 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Jordan Niethe's on March 20, 2020 3:17 pm:
>> > Currently unsigned ints are used to represent instructions on powerpc.
>> > This has worked well as instructions have always been 4 byte words.
>> > However, a future ISA version will introduce some changes to
>> > instructions that mean this scheme will no longer work as well. This
>> > change is Prefixed Instructions. A prefixed instruction is made up of a
>> > word prefix followed by a word suffix to make an 8 byte double word
>> > instruction. No matter the endianess of the system the prefix always
>> > comes first. Prefixed instructions are only planned for powerpc64.
>> >
>> > Introduce a ppc_inst type to represent both prefixed and word
>> > instructions on powerpc64 while keeping it possible to exclusively have
>> > word instructions on powerpc32, A latter patch will expand the type to
>> > include prefixed instructions but for now just typedef it to a u32.
>> >
>> > Later patches will introduce helper functions and macros for
>> > manipulating the instructions so that powerpc64 and powerpc32 might
>> > maintain separate type definitions.
>>
>> ppc_inst_t I would slightly prefer for a typedef like this.
> Are _t types meant to be reserved?

No, just convention that structs are not normally typedefed unless
they are a pervasive interface that gets passed around a lot but
does not get accessed without accessor functions much. When you do
typedef them, add a _t (or less frequently _s/_u/etc). pte_t,
cpumask_t, atomic_t.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 16/16] powerpc sstep: Add support for prefixed fixed-point arithmetic
  2020-03-20  5:18 ` [PATCH v4 16/16] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
@ 2020-03-23 10:05   ` Balamuruhan S
  0 siblings, 0 replies; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23 10:05 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Fri, 2020-03-20 at 16:18 +1100, Jordan Niethe wrote:
> This adds emulation support for the following prefixed Fixed-Point
> Arithmetic instructions:
>   * Prefixed Add Immediate (paddi)
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>

Reviewed-by: Balamuruhan S <bala24@linux.ibm.com>

> ---
> v3: Since we moved the prefixed loads/stores into the load/store switch
> statement it no longer makes sense to have paddi in there, so move it
> out.
> ---
>  arch/powerpc/lib/sstep.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index daef70eb8e22..6862fc019258 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1335,6 +1335,26 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  	switch (opcode) {
>  #ifdef __powerpc64__
> +	case 1:
> +		prefix_r = word & (1ul << 20);
> +		ra = (suffix >> 16) & 0x1f;
> +		rd = (suffix >> 21) & 0x1f;
> +		op->reg = rd;
> +		op->val = regs->gpr[rd];
> +		suffixopcode = suffix >> 26;
> +		prefixtype = (word >> 24) & 0x3;
> +		switch (prefixtype) {
> +		case 2:
> +			if (prefix_r && ra)
> +				return 0;
> +			switch (suffixopcode) {
> +			case 14:	/* paddi */
> +				op->type = COMPUTE | PREFIXED;
> +				op->val = mlsd_8lsd_ea(word, suffix, regs);
> +				goto compute_done;
> +			}
> +		}
> +		break;
>  	case 2:		/* tdi */
>  		if (rd & trap_compare(regs->gpr[ra], (short) word))
>  			goto trap;


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 09/16] powerpc: Use a function for reading instructions
  2020-03-23  8:00   ` Nicholas Piggin
  2020-03-23  8:43     ` Balamuruhan S
@ 2020-03-23 10:09     ` Jordan Niethe
  2020-03-23 10:36       ` Nicholas Piggin
  1 sibling, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23 10:09 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 7:03 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:18 pm:
> > Prefixed instructions will mean there are instructions of different
> > length. As a result dereferencing a pointer to an instruction will not
> > necessarily give the desired result. Introduce a function for reading
> > instructions from memory into the instruction data type.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v4: New to series
> > ---
> >  arch/powerpc/include/asm/uprobes.h |  4 ++--
> >  arch/powerpc/kernel/kprobes.c      |  8 ++++----
> >  arch/powerpc/kernel/mce_power.c    |  2 +-
> >  arch/powerpc/kernel/optprobes.c    |  6 +++---
> >  arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++-----------
> >  arch/powerpc/kernel/uprobes.c      |  2 +-
> >  arch/powerpc/lib/code-patching.c   | 22 ++++++++++----------
> >  arch/powerpc/lib/feature-fixups.c  |  6 +++---
> >  arch/powerpc/xmon/xmon.c           |  6 +++---
> >  9 files changed, 49 insertions(+), 40 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
> > index 2bbdf27d09b5..fff3c5fc90b5 100644
> > --- a/arch/powerpc/include/asm/uprobes.h
> > +++ b/arch/powerpc/include/asm/uprobes.h
> > @@ -23,8 +23,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
> >
> >  struct arch_uprobe {
> >       union {
> > -             u32     insn;
> > -             u32     ixol;
> > +             u8      insn[MAX_UINSN_BYTES];
> > +             u8      ixol[MAX_UINSN_BYTES];
> >       };
> >  };
>
> Hmm. I wonder if this should be a different patch. Not sure if raw
> bytes is a good idea here. ppc probes also has a ppc_opcode_t, maybe
> could be replaced with ppc_insn_t and used here instead?
You are right this should not really be in this patch. I felt bytes
made sense as we have  MAX_UINSN_BYTES, which could be updated once
prefixed instructions were introduced.
By replace do you mean define uprobe_opcode_t as ppc_inst_t instead of
ppc_opcode_t? That will not really work with the arch indep code in
places like:

bool __weak is_swbp_insn(uprobe_opcode_t *insn)
{
    return *insn == UPROBE_SWBP_INSN;
}

Or do you mean something like this:
  struct arch_uprobe {
       union {
 -             u32     insn;
 -             u32     ixol;
 +             pcc_inst_t     insn;
 +             ppc_inst_t     ixol;
       };
 };

>
> Also can't find where you define ppc_inst_read.
>
> > diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
> > index 7614a9f537fd..ad451205f268 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -41,6 +41,12 @@
> >  #define      NUM_FTRACE_TRAMPS       8
> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> >
> > +static long
> > +read_inst(ppc_inst *inst, const void *src)
> > +{
> > +     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> > +}
>
> Humbly suggest probe_kernel_inst_read.
The other probe_kernel_*  functions were from generic code so I
thought it might be misleading to call it that.
>
> Thanks,
> Nick
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 00/16] Initial Prefixed Instruction support
  2020-03-23  9:25   ` Jordan Niethe
@ 2020-03-23 10:17     ` Nicholas Piggin
  2020-03-24  2:54       ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23 10:17 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

Jordan Niethe's on March 23, 2020 7:25 pm:
> On Mon, Mar 23, 2020 at 5:22 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Jordan Niethe's on March 20, 2020 3:17 pm:
>> > A future revision of the ISA will introduce prefixed instructions. A
>> > prefixed instruction is composed of a 4-byte prefix followed by a
>> > 4-byte suffix.
>> >
>> > All prefixes have the major opcode 1. A prefix will never be a valid
>> > word instruction. A suffix may be an existing word instruction or a
>> > new instruction.
>> >
>> > This series enables prefixed instructions and extends the instruction
>> > emulation to support them. Then the places where prefixed instructions
>> > might need to be emulated are updated.
>> >
>> > The series is based on top of:
>> > https://patchwork.ozlabs.org/patch/1232619/ as this will effect
>> > kprobes.
>> >
>> > v4 is based on feedback from Nick Piggins, Christophe Leroy and Daniel Axtens.
>> > The major changes:
>> >     - Move xmon breakpoints from data section to text section
>> >     - Introduce a data type for instructions on powerpc
>>
>> Thanks for doing this, looks like a lot of work, I hope it works out :)
>>
> Yes it did end up touching a lot of places. I started thinking that
> that maybe it would be simpler to just use a u64 instead of the struct
> for  instructions.
> If we always keep the word instruction / prefix in the lower bytes,
> all of the current masking should still work and we can use operators
> again instead of ppc_inst_equal(), etc.

Yeah.. I think now that you've done it, I prefer it this way.

> It also makes printing easier. We could just #define INST_FMT %llx or
> #define INST_FMT %x on powerpc32 and use that for printing out
> instructions.

Well, not sure about that. Would it make endian concerns more
complicated? Print format for prefix might be '%016llx', but we
don't want that for all instructions only prefixed ones, and I
don't know if that is the way to go either.

We'll want to adopt some convention for displaying prefixed
instruction bytes, but I don't know what what works best. I wonder
if binutils or any userspace tools have a convention.

Which reminds me, you might have missed show_instructions()?
Although maybe you don't need that until we start using them in
the kernel.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 09/16] powerpc: Use a function for reading instructions
  2020-03-23 10:09     ` Jordan Niethe
@ 2020-03-23 10:36       ` Nicholas Piggin
  0 siblings, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-23 10:36 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

Jordan Niethe's on March 23, 2020 8:09 pm:
> On Mon, Mar 23, 2020 at 7:03 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Jordan Niethe's on March 20, 2020 3:18 pm:
>> > Prefixed instructions will mean there are instructions of different
>> > length. As a result dereferencing a pointer to an instruction will not
>> > necessarily give the desired result. Introduce a function for reading
>> > instructions from memory into the instruction data type.
>> >
>> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
>> > ---
>> > v4: New to series
>> > ---
>> >  arch/powerpc/include/asm/uprobes.h |  4 ++--
>> >  arch/powerpc/kernel/kprobes.c      |  8 ++++----
>> >  arch/powerpc/kernel/mce_power.c    |  2 +-
>> >  arch/powerpc/kernel/optprobes.c    |  6 +++---
>> >  arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++-----------
>> >  arch/powerpc/kernel/uprobes.c      |  2 +-
>> >  arch/powerpc/lib/code-patching.c   | 22 ++++++++++----------
>> >  arch/powerpc/lib/feature-fixups.c  |  6 +++---
>> >  arch/powerpc/xmon/xmon.c           |  6 +++---
>> >  9 files changed, 49 insertions(+), 40 deletions(-)
>> >
>> > diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
>> > index 2bbdf27d09b5..fff3c5fc90b5 100644
>> > --- a/arch/powerpc/include/asm/uprobes.h
>> > +++ b/arch/powerpc/include/asm/uprobes.h
>> > @@ -23,8 +23,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
>> >
>> >  struct arch_uprobe {
>> >       union {
>> > -             u32     insn;
>> > -             u32     ixol;
>> > +             u8      insn[MAX_UINSN_BYTES];
>> > +             u8      ixol[MAX_UINSN_BYTES];
>> >       };
>> >  };
>>
>> Hmm. I wonder if this should be a different patch. Not sure if raw
>> bytes is a good idea here. ppc probes also has a ppc_opcode_t, maybe
>> could be replaced with ppc_insn_t and used here instead?
> You are right this should not really be in this patch. I felt bytes
> made sense as we have  MAX_UINSN_BYTES, which could be updated once
> prefixed instructions were introduced.

Okay.

> By replace do you mean define uprobe_opcode_t as ppc_inst_t instead of
> ppc_opcode_t? That will not really work with the arch indep code in
> places like:
> 
> bool __weak is_swbp_insn(uprobe_opcode_t *insn)
> {
>     return *insn == UPROBE_SWBP_INSN;
> }

Ah, yeah I did mean that, you probably told me that already.

> Or do you mean something like this:
>   struct arch_uprobe {
>        union {
>  -             u32     insn;
>  -             u32     ixol;
>  +             pcc_inst_t     insn;
>  +             ppc_inst_t     ixol;
>        };
>  };

I didn't mean that, but it would be nicer than the change you've got,
if it works.

>> Also can't find where you define ppc_inst_read.
>>
>> > diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
>> > index 7614a9f537fd..ad451205f268 100644
>> > --- a/arch/powerpc/kernel/trace/ftrace.c
>> > +++ b/arch/powerpc/kernel/trace/ftrace.c
>> > @@ -41,6 +41,12 @@
>> >  #define      NUM_FTRACE_TRAMPS       8
>> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
>> >
>> > +static long
>> > +read_inst(ppc_inst *inst, const void *src)
>> > +{
>> > +     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
>> > +}
>>
>> Humbly suggest probe_kernel_inst_read.
> The other probe_kernel_*  functions were from generic code so I
> thought it might be misleading to call it that.

It's probably not too bad, you could add a __ or ppc_ prefix if
it would help?

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 08/16] powerpc: Use an accessor for word instructions
  2020-03-20  5:18 ` [PATCH v4 08/16] powerpc: Use an accessor for word instructions Jordan Niethe
@ 2020-03-23 11:12   ` Balamuruhan S
  2020-03-24  3:18     ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Balamuruhan S @ 2020-03-23 11:12 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Fri, 2020-03-20 at 16:18 +1100, Jordan Niethe wrote:
> In preparation for prefixed instructions where all instructions are no
> longer words, use an accessor for getting a word instruction as a u32
> from the instruction data type.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/kernel/align.c          |   2 +-
>  arch/powerpc/kernel/kprobes.c        |   2 +-
>  arch/powerpc/kernel/trace/ftrace.c   |  16 +-
>  arch/powerpc/lib/code-patching.c     |   2 +-
>  arch/powerpc/lib/feature-fixups.c    |   4 +-
>  arch/powerpc/lib/sstep.c             | 270 ++++++++++++++-------------
>  arch/powerpc/lib/test_emulate_step.c |   4 +-
>  arch/powerpc/xmon/xmon.c             |   4 +-
>  8 files changed, 153 insertions(+), 151 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index 77c49dfdc1b4..b246ca124931 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -309,7 +309,7 @@ int fix_alignment(struct pt_regs *regs)
>  		/* We don't handle PPC little-endian any more... */
>  		if (cpu_has_feature(CPU_FTR_PPC_LE))
>  			return -EIO;
> -		instr = PPC_INST(swab32(instr));
> +		instr = PPC_INST(swab32(ppc_inst_word(instr)));
>  	}
>  
>  #ifdef CONFIG_SPE
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 4c2b656615a6..0c600b6e4ead 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -242,7 +242,7 @@ static int try_to_emulate(struct kprobe *p, struct
> pt_regs *regs)
>  		 * So, we should never get here... but, its still
>  		 * good to catch them, just in case...
>  		 */
> -		printk("Can't step on instruction %x\n", insn);
> +		printk("Can't step on instruction %x\n", ppc_inst_word(insn));
>  		BUG();
>  	} else {
>  		/*
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c
> index b3645b664819..7614a9f537fd 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -74,7 +74,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst
> new)
>  	/* Make sure it is what we expect it to be */
>  	if (!ppc_inst_equal(replaced, old)) {
>  		pr_err("%p: replaced (%#x) != old (%#x)",
> -		(void *)ip, replaced, old);
> +		(void *)ip, ppc_inst_word(replaced), ppc_inst_word(old));
>  		return -EINVAL;
>  	}
>  
> @@ -136,7 +136,7 @@ __ftrace_make_nop(struct module *mod,
>  
>  	/* Make sure that that this is still a 24bit jump */
>  	if (!is_bl_op(op)) {
> -		pr_err("Not expected bl: opcode is %x\n", op);
> +		pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
>  		return -EINVAL;
>  	}
>  
> @@ -171,7 +171,7 @@ __ftrace_make_nop(struct module *mod,
>  	/* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
>  	if (!ppc_inst_equal(op, PPC_INST(PPC_INST_MFLR)) &&
>  	    !ppc_inst_equal(op, PPC_INST(PPC_INST_STD_LR))) {
> -		pr_err("Unexpected instruction %08x around bl _mcount\n", op);
> +		pr_err("Unexpected instruction %08x around bl _mcount\n",
> ppc_inst_word(op));
>  		return -EINVAL;
>  	}
>  #else
> @@ -201,7 +201,7 @@ __ftrace_make_nop(struct module *mod,
>  	}
>  
>  	if (!ppc_inst_equal(op,  PPC_INST(PPC_INST_LD_TOC))) {
> -		pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op);
> +		pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC,
> ppc_inst_word(op));
>  		return -EINVAL;
>  	}
>  #endif /* CONFIG_MPROFILE_KERNEL */
> @@ -401,7 +401,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  
>  	/* Make sure that that this is still a 24bit jump */
>  	if (!is_bl_op(op)) {
> -		pr_err("Not expected bl: opcode is %x\n", op);
> +		pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
>  		return -EINVAL;
>  	}
>  
> @@ -525,7 +525,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  
>  	if (!expected_nop_sequence(ip, op[0], op[1])) {
>  		pr_err("Unexpected call sequence at %p: %x %x\n",
> -		ip, op[0], op[1]);
> +		ip, ppc_inst_word(op[0]), ppc_inst_word(op[1]));
>  		return -EINVAL;
>  	}
>  
> @@ -644,7 +644,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  	}
>  
>  	if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) {
> -		pr_err("Unexpected call sequence at %p: %x\n", ip, op);
> +		pr_err("Unexpected call sequence at %p: %x\n", ip,
> ppc_inst_word(op));
>  		return -EINVAL;
>  	}
>  
> @@ -723,7 +723,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  
>  	/* Make sure that that this is still a 24bit jump */
>  	if (!is_bl_op(op)) {
> -		pr_err("Not expected bl: opcode is %x\n", op);
> +		pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
>  		return -EINVAL;
>  	}
>  
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index ec3abe1a6927..849eee63df3d 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -233,7 +233,7 @@ bool is_conditional_branch(ppc_inst instr)
>  	if (opcode == 16)       /* bc, bca, bcl, bcla */
>  		return true;
>  	if (opcode == 19) {
> -		switch ((instr >> 1) & 0x3ff) {
> +		switch ((ppc_inst_word(instr) >> 1) & 0x3ff) {
>  		case 16:        /* bclr, bclrl */
>  		case 528:       /* bcctr, bcctrl */
>  		case 560:       /* bctar, bctarl */
> diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> fixups.c
> index 552106d1f64a..fe8ec099aa96 100644
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -54,8 +54,8 @@ static int patch_alt_instruction(unsigned int *src,
> unsigned int *dest,
>  
>  		/* Branch within the section doesn't need translating */
>  		if (target < alt_start || target > alt_end) {
> -			instr = translate_branch(dest, src);
> -			if (ppc_inst_null(instr))
> +			instr = ppc_inst_word(translate_branch((ppc_inst
> *)dest, (ppc_inst *)src));
> +			if (!instr)
>  				return 1;
>  		}
>  	}
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 1d9c766a89fe..bae878a83fa5 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1169,26 +1169,28 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  	unsigned long int imm;
>  	unsigned long int val, val2;
>  	unsigned int mb, me, sh;
> +	unsigned int word;
>  	long ival;
>  
> +	word = ppc_inst_word(instr);
>  	op->type = COMPUTE;
>  
> -	opcode = instr >> 26;
> +	opcode = word >> 26;
>  	switch (opcode) {
>  	case 16:	/* bc */
>  		op->type = BRANCH;
> -		imm = (signed short)(instr & 0xfffc);
> -		if ((instr & 2) == 0)
> +		imm = (signed short)(word & 0xfffc);
> +		if ((word & 2) == 0)
>  			imm += regs->nip;
>  		op->val = truncate_if_32bit(regs->msr, imm);
> -		if (instr & 1)
> +		if (word & 1)
>  			op->type |= SETLK;
> -		if (branch_taken(instr, regs, op))
> +		if (branch_taken(word, regs, op))
>  			op->type |= BRTAKEN;
>  		return 1;
>  #ifdef CONFIG_PPC64
>  	case 17:	/* sc */
> -		if ((instr & 0xfe2) == 2)
> +		if ((word & 0xfe2) == 2)
>  			op->type = SYSCALL;
>  		else
>  			op->type = UNKNOWN;
> @@ -1196,21 +1198,21 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  #endif
>  	case 18:	/* b */
>  		op->type = BRANCH | BRTAKEN;
> -		imm = instr & 0x03fffffc;
> +		imm = word & 0x03fffffc;
>  		if (imm & 0x02000000)
>  			imm -= 0x04000000;
> -		if ((instr & 2) == 0)
> +		if ((word & 2) == 0)
>  			imm += regs->nip;
>  		op->val = truncate_if_32bit(regs->msr, imm);
> -		if (instr & 1)
> +		if (word & 1)
>  			op->type |= SETLK;
>  		return 1;
>  	case 19:
> -		switch ((instr >> 1) & 0x3ff) {
> +		switch ((word >> 1) & 0x3ff) {
>  		case 0:		/* mcrf */
>  			op->type = COMPUTE + SETCC;
> -			rd = 7 - ((instr >> 23) & 0x7);
> -			ra = 7 - ((instr >> 18) & 0x7);
> +			rd = 7 - ((word >> 23) & 0x7);
> +			ra = 7 - ((word >> 18) & 0x7);
>  			rd *= 4;
>  			ra *= 4;
>  			val = (regs->ccr >> ra) & 0xf;
> @@ -1220,11 +1222,11 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		case 16:	/* bclr */
>  		case 528:	/* bcctr */
>  			op->type = BRANCH;
> -			imm = (instr & 0x400)? regs->ctr: regs->link;
> +			imm = (word & 0x400)? regs->ctr: regs->link;
>  			op->val = truncate_if_32bit(regs->msr, imm);
> -			if (instr & 1)
> +			if (word & 1)
>  				op->type |= SETLK;
> -			if (branch_taken(instr, regs, op))
> +			if (branch_taken(word, regs, op))
>  				op->type |= BRTAKEN;
>  			return 1;
>  
> @@ -1247,23 +1249,23 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		case 417:	/* crorc */
>  		case 449:	/* cror */
>  			op->type = COMPUTE + SETCC;
> -			ra = (instr >> 16) & 0x1f;
> -			rb = (instr >> 11) & 0x1f;
> -			rd = (instr >> 21) & 0x1f;
> +			ra = (word >> 16) & 0x1f;
> +			rb = (word >> 11) & 0x1f;
> +			rd = (word >> 21) & 0x1f;

can't we use your accessors for all these operations ?

>  			ra = (regs->ccr >> (31 - ra)) & 1;
>  			rb = (regs->ccr >> (31 - rb)) & 1;
> -			val = (instr >> (6 + ra * 2 + rb)) & 1;
> +			val = (word >> (6 + ra * 2 + rb)) & 1;
>  			op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
>  				(val << (31 - rd));
>  			return 1;
>  		}
>  		break;
>  	case 31:
> -		switch ((instr >> 1) & 0x3ff) {
> +		switch ((word >> 1) & 0x3ff) {
>  		case 598:	/* sync */
>  			op->type = BARRIER + BARRIER_SYNC;
>  #ifdef __powerpc64__
> -			switch ((instr >> 21) & 3) {
> +			switch ((word >> 21) & 3) {
>  			case 1:		/* lwsync */
>  				op->type = BARRIER + BARRIER_LWSYNC;
>  				break;
> @@ -1285,20 +1287,20 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  	if (!FULL_REGS(regs))
>  		return -1;
>  
> -	rd = (instr >> 21) & 0x1f;
> -	ra = (instr >> 16) & 0x1f;
> -	rb = (instr >> 11) & 0x1f;
> -	rc = (instr >> 6) & 0x1f;
> +	rd = (word >> 21) & 0x1f;
> +	ra = (word >> 16) & 0x1f;
> +	rb = (word >> 11) & 0x1f;
> +	rc = (word >> 6) & 0x1f;

same here and in similar such places.

-- Bala
>  
>  	switch (opcode) {
>  #ifdef __powerpc64__
>  	case 2:		/* tdi */
> -		if (rd & trap_compare(regs->gpr[ra], (short) instr))
> +		if (rd & trap_compare(regs->gpr[ra], (short) word))
>  			goto trap;
>  		return 1;
>  #endif
>  	case 3:		/* twi */
> -		if (rd & trap_compare((int)regs->gpr[ra], (short) instr))
> +		if (rd & trap_compare((int)regs->gpr[ra], (short) word))
>  			goto trap;
>  		return 1;
>  
> @@ -1307,7 +1309,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		if (!cpu_has_feature(CPU_FTR_ARCH_300))
>  			return -1;
>  
> -		switch (instr & 0x3f) {
> +		switch (word & 0x3f) {
>  		case 48:	/* maddhd */
>  			asm volatile(PPC_MADDHD(%0, %1, %2, %3) :
>  				     "=r" (op->val) : "r" (regs->gpr[ra]),
> @@ -1335,16 +1337,16 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  #endif
>  
>  	case 7:		/* mulli */
> -		op->val = regs->gpr[ra] * (short) instr;
> +		op->val = regs->gpr[ra] * (short) word;
>  		goto compute_done;
>  
>  	case 8:		/* subfic */
> -		imm = (short) instr;
> +		imm = (short) word;
>  		add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1);
>  		return 1;
>  
>  	case 10:	/* cmpli */
> -		imm = (unsigned short) instr;
> +		imm = (unsigned short) word;
>  		val = regs->gpr[ra];
>  #ifdef __powerpc64__
>  		if ((rd & 1) == 0)
> @@ -1354,7 +1356,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		return 1;
>  
>  	case 11:	/* cmpi */
> -		imm = (short) instr;
> +		imm = (short) word;
>  		val = regs->gpr[ra];
>  #ifdef __powerpc64__
>  		if ((rd & 1) == 0)
> @@ -1364,35 +1366,35 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		return 1;
>  
>  	case 12:	/* addic */
> -		imm = (short) instr;
> +		imm = (short) word;
>  		add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
>  		return 1;
>  
>  	case 13:	/* addic. */
> -		imm = (short) instr;
> +		imm = (short) word;
>  		add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
>  		set_cr0(regs, op);
>  		return 1;
>  
>  	case 14:	/* addi */
> -		imm = (short) instr;
> +		imm = (short) word;
>  		if (ra)
>  			imm += regs->gpr[ra];
>  		op->val = imm;
>  		goto compute_done;
>  
>  	case 15:	/* addis */
> -		imm = ((short) instr) << 16;
> +		imm = ((short) word) << 16;
>  		if (ra)
>  			imm += regs->gpr[ra];
>  		op->val = imm;
>  		goto compute_done;
>  
>  	case 19:
> -		if (((instr >> 1) & 0x1f) == 2) {
> +		if (((word >> 1) & 0x1f) == 2) {
>  			/* addpcis */
> -			imm = (short) (instr & 0xffc1);	/* d0 + d2 fields */
> -			imm |= (instr >> 15) & 0x3e;	/* d1 field */
> +			imm = (short) (word & 0xffc1);	/* d0 + d2 fields */
> +			imm |= (word >> 15) & 0x3e;	/* d1 field */
>  			op->val = regs->nip + (imm << 16) + 4;
>  			goto compute_done;
>  		}
> @@ -1400,65 +1402,65 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		return 0;
>  
>  	case 20:	/* rlwimi */
> -		mb = (instr >> 6) & 0x1f;
> -		me = (instr >> 1) & 0x1f;
> +		mb = (word >> 6) & 0x1f;
> +		me = (word >> 1) & 0x1f;
>  		val = DATA32(regs->gpr[rd]);
>  		imm = MASK32(mb, me);
>  		op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm);
>  		goto logical_done;
>  
>  	case 21:	/* rlwinm */
> -		mb = (instr >> 6) & 0x1f;
> -		me = (instr >> 1) & 0x1f;
> +		mb = (word >> 6) & 0x1f;
> +		me = (word >> 1) & 0x1f;
>  		val = DATA32(regs->gpr[rd]);
>  		op->val = ROTATE(val, rb) & MASK32(mb, me);
>  		goto logical_done;
>  
>  	case 23:	/* rlwnm */
> -		mb = (instr >> 6) & 0x1f;
> -		me = (instr >> 1) & 0x1f;
> +		mb = (word >> 6) & 0x1f;
> +		me = (word >> 1) & 0x1f;
>  		rb = regs->gpr[rb] & 0x1f;
>  		val = DATA32(regs->gpr[rd]);
>  		op->val = ROTATE(val, rb) & MASK32(mb, me);
>  		goto logical_done;
>  
>  	case 24:	/* ori */
> -		op->val = regs->gpr[rd] | (unsigned short) instr;
> +		op->val = regs->gpr[rd] | (unsigned short) word;
>  		goto logical_done_nocc;
>  
>  	case 25:	/* oris */
> -		imm = (unsigned short) instr;
> +		imm = (unsigned short) word;
>  		op->val = regs->gpr[rd] | (imm << 16);
>  		goto logical_done_nocc;
>  
>  	case 26:	/* xori */
> -		op->val = regs->gpr[rd] ^ (unsigned short) instr;
> +		op->val = regs->gpr[rd] ^ (unsigned short) word;
>  		goto logical_done_nocc;
>  
>  	case 27:	/* xoris */
> -		imm = (unsigned short) instr;
> +		imm = (unsigned short) word;
>  		op->val = regs->gpr[rd] ^ (imm << 16);
>  		goto logical_done_nocc;
>  
>  	case 28:	/* andi. */
> -		op->val = regs->gpr[rd] & (unsigned short) instr;
> +		op->val = regs->gpr[rd] & (unsigned short) word;
>  		set_cr0(regs, op);
>  		goto logical_done_nocc;
>  
>  	case 29:	/* andis. */
> -		imm = (unsigned short) instr;
> +		imm = (unsigned short) word;
>  		op->val = regs->gpr[rd] & (imm << 16);
>  		set_cr0(regs, op);
>  		goto logical_done_nocc;
>  
>  #ifdef __powerpc64__
>  	case 30:	/* rld* */
> -		mb = ((instr >> 6) & 0x1f) | (instr & 0x20);
> +		mb = ((word >> 6) & 0x1f) | (word & 0x20);
>  		val = regs->gpr[rd];
> -		if ((instr & 0x10) == 0) {
> -			sh = rb | ((instr & 2) << 4);
> +		if ((word & 0x10) == 0) {
> +			sh = rb | ((word & 2) << 4);
>  			val = ROTATE(val, sh);
> -			switch ((instr >> 2) & 3) {
> +			switch ((word >> 2) & 3) {
>  			case 0:		/* rldicl */
>  				val &= MASK64_L(mb);
>  				break;
> @@ -1478,7 +1480,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		} else {
>  			sh = regs->gpr[rb] & 0x3f;
>  			val = ROTATE(val, sh);
> -			switch ((instr >> 1) & 7) {
> +			switch ((word >> 1) & 7) {
>  			case 0:		/* rldcl */
>  				op->val = val & MASK64_L(mb);
>  				goto logical_done;
> @@ -1493,8 +1495,8 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  	case 31:
>  		/* isel occupies 32 minor opcodes */
> -		if (((instr >> 1) & 0x1f) == 15) {
> -			mb = (instr >> 6) & 0x1f; /* bc field */
> +		if (((word >> 1) & 0x1f) == 15) {
> +			mb = (word >> 6) & 0x1f; /* bc field */
>  			val = (regs->ccr >> (31 - mb)) & 1;
>  			val2 = (ra) ? regs->gpr[ra] : 0;
>  
> @@ -1502,7 +1504,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			goto compute_done;
>  		}
>  
> -		switch ((instr >> 1) & 0x3ff) {
> +		switch ((word >> 1) & 0x3ff) {
>  		case 4:		/* tw */
>  			if (rd == 0x1f ||
>  			    (rd & trap_compare((int)regs->gpr[ra],
> @@ -1536,17 +1538,17 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			op->reg = rd;
>  			/* only MSR_EE and MSR_RI get changed if bit 15 set */
>  			/* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */
> -			imm = (instr & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
> +			imm = (word & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
>  			op->val = imm;
>  			return 0;
>  #endif
>  
>  		case 19:	/* mfcr */
>  			imm = 0xffffffffUL;
> -			if ((instr >> 20) & 1) {
> +			if ((word >> 20) & 1) {
>  				imm = 0xf0000000UL;
>  				for (sh = 0; sh < 8; ++sh) {
> -					if (instr & (0x80000 >> sh))
> +					if (word & (0x80000 >> sh))
>  						break;
>  					imm >>= 4;
>  				}
> @@ -1560,7 +1562,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			val = regs->gpr[rd];
>  			op->ccval = regs->ccr;
>  			for (sh = 0; sh < 8; ++sh) {
> -				if (instr & (0x80000 >> sh))
> +				if (word & (0x80000 >> sh))
>  					op->ccval = (op->ccval & ~imm) |
>  						(val & imm);
>  				imm >>= 4;
> @@ -1568,7 +1570,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			return 1;
>  
>  		case 339:	/* mfspr */
> -			spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
> +			spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
>  			op->type = MFSPR;
>  			op->reg = rd;
>  			op->spr = spr;
> @@ -1578,7 +1580,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			return 0;
>  
>  		case 467:	/* mtspr */
> -			spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
> +			spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
>  			op->type = MTSPR;
>  			op->val = regs->gpr[rd];
>  			op->spr = spr;
> @@ -1948,7 +1950,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		case 826:	/* sradi with sh_5 = 0 */
>  		case 827:	/* sradi with sh_5 = 1 */
>  			op->type = COMPUTE + SETREG + SETXER;
> -			sh = rb | ((instr & 2) << 4);
> +			sh = rb | ((word & 2) << 4);
>  			ival = (signed long int) regs->gpr[rd];
>  			op->val = ival >> sh;
>  			op->xerval = regs->xer;
> @@ -1964,7 +1966,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			if (!cpu_has_feature(CPU_FTR_ARCH_300))
>  				return -1;
>  			op->type = COMPUTE + SETREG;
> -			sh = rb | ((instr & 2) << 4);
> +			sh = rb | ((word & 2) << 4);
>  			val = (signed int) regs->gpr[rd];
>  			if (sh)
>  				op->val = ROTATE(val, sh) & MASK64(0, 63 - sh);
> @@ -1979,34 +1981,34 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>   */
>  		case 54:	/* dcbst */
>  			op->type = MKOP(CACHEOP, DCBST, 0);
> -			op->ea = xform_ea(instr, regs);
> +			op->ea = xform_ea(word, regs);
>  			return 0;
>  
>  		case 86:	/* dcbf */
>  			op->type = MKOP(CACHEOP, DCBF, 0);
> -			op->ea = xform_ea(instr, regs);
> +			op->ea = xform_ea(word, regs);
>  			return 0;
>  
>  		case 246:	/* dcbtst */
>  			op->type = MKOP(CACHEOP, DCBTST, 0);
> -			op->ea = xform_ea(instr, regs);
> +			op->ea = xform_ea(word, regs);
>  			op->reg = rd;
>  			return 0;
>  
>  		case 278:	/* dcbt */
>  			op->type = MKOP(CACHEOP, DCBTST, 0);
> -			op->ea = xform_ea(instr, regs);
> +			op->ea = xform_ea(word, regs);
>  			op->reg = rd;
>  			return 0;
>  
>  		case 982:	/* icbi */
>  			op->type = MKOP(CACHEOP, ICBI, 0);
> -			op->ea = xform_ea(instr, regs);
> +			op->ea = xform_ea(word, regs);
>  			return 0;
>  
>  		case 1014:	/* dcbz */
>  			op->type = MKOP(CACHEOP, DCBZ, 0);
> -			op->ea = xform_ea(instr, regs);
> +			op->ea = xform_ea(word, regs);
>  			return 0;
>  		}
>  		break;
> @@ -2019,14 +2021,14 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  	op->update_reg = ra;
>  	op->reg = rd;
>  	op->val = regs->gpr[rd];
> -	u = (instr >> 20) & UPDATE;
> +	u = (word >> 20) & UPDATE;
>  	op->vsx_flags = 0;
>  
>  	switch (opcode) {
>  	case 31:
> -		u = instr & UPDATE;
> -		op->ea = xform_ea(instr, regs);
> -		switch ((instr >> 1) & 0x3ff) {
> +		u = word & UPDATE;
> +		op->ea = xform_ea(word, regs);
> +		switch ((word >> 1) & 0x3ff) {
>  		case 20:	/* lwarx */
>  			op->type = MKOP(LARX, 0, 4);
>  			break;
> @@ -2271,25 +2273,25 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  #ifdef CONFIG_VSX
>  		case 12:	/* lxsiwzx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 4);
>  			op->element_size = 8;
>  			break;
>  
>  		case 76:	/* lxsiwax */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, SIGNEXT, 4);
>  			op->element_size = 8;
>  			break;
>  
>  		case 140:	/* stxsiwx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 4);
>  			op->element_size = 8;
>  			break;
>  
>  		case 268:	/* lxvx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 16);
>  			op->element_size = 16;
>  			op->vsx_flags = VSX_CHECK_VEC;
> @@ -2298,33 +2300,33 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		case 269:	/* lxvl */
>  		case 301: {	/* lxvll */
>  			int nb;
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->ea = ra ? regs->gpr[ra] : 0;
>  			nb = regs->gpr[rb] & 0xff;
>  			if (nb > 16)
>  				nb = 16;
>  			op->type = MKOP(LOAD_VSX, 0, nb);
>  			op->element_size = 16;
> -			op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
> +			op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
>  				VSX_CHECK_VEC;
>  			break;
>  		}
>  		case 332:	/* lxvdsx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 8);
>  			op->element_size = 8;
>  			op->vsx_flags = VSX_SPLAT;
>  			break;
>  
>  		case 364:	/* lxvwsx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 4);
>  			op->element_size = 4;
>  			op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC;
>  			break;
>  
>  		case 396:	/* stxvx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 16);
>  			op->element_size = 16;
>  			op->vsx_flags = VSX_CHECK_VEC;
> @@ -2333,118 +2335,118 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  		case 397:	/* stxvl */
>  		case 429: {	/* stxvll */
>  			int nb;
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->ea = ra ? regs->gpr[ra] : 0;
>  			nb = regs->gpr[rb] & 0xff;
>  			if (nb > 16)
>  				nb = 16;
>  			op->type = MKOP(STORE_VSX, 0, nb);
>  			op->element_size = 16;
> -			op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
> +			op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
>  				VSX_CHECK_VEC;
>  			break;
>  		}
>  		case 524:	/* lxsspx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 4);
>  			op->element_size = 8;
>  			op->vsx_flags = VSX_FPCONV;
>  			break;
>  
>  		case 588:	/* lxsdx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 8);
>  			op->element_size = 8;
>  			break;
>  
>  		case 652:	/* stxsspx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 4);
>  			op->element_size = 8;
>  			op->vsx_flags = VSX_FPCONV;
>  			break;
>  
>  		case 716:	/* stxsdx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 8);
>  			op->element_size = 8;
>  			break;
>  
>  		case 780:	/* lxvw4x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 16);
>  			op->element_size = 4;
>  			break;
>  
>  		case 781:	/* lxsibzx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 1);
>  			op->element_size = 8;
>  			op->vsx_flags = VSX_CHECK_VEC;
>  			break;
>  
>  		case 812:	/* lxvh8x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 16);
>  			op->element_size = 2;
>  			op->vsx_flags = VSX_CHECK_VEC;
>  			break;
>  
>  		case 813:	/* lxsihzx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 2);
>  			op->element_size = 8;
>  			op->vsx_flags = VSX_CHECK_VEC;
>  			break;
>  
>  		case 844:	/* lxvd2x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 16);
>  			op->element_size = 8;
>  			break;
>  
>  		case 876:	/* lxvb16x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(LOAD_VSX, 0, 16);
>  			op->element_size = 1;
>  			op->vsx_flags = VSX_CHECK_VEC;
>  			break;
>  
>  		case 908:	/* stxvw4x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 16);
>  			op->element_size = 4;
>  			break;
>  
>  		case 909:	/* stxsibx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 1);
>  			op->element_size = 8;
>  			op->vsx_flags = VSX_CHECK_VEC;
>  			break;
>  
>  		case 940:	/* stxvh8x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 16);
>  			op->element_size = 2;
>  			op->vsx_flags = VSX_CHECK_VEC;
>  			break;
>  
>  		case 941:	/* stxsihx */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 2);
>  			op->element_size = 8;
>  			op->vsx_flags = VSX_CHECK_VEC;
>  			break;
>  
>  		case 972:	/* stxvd2x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 16);
>  			op->element_size = 8;
>  			break;
>  
>  		case 1004:	/* stxvb16x */
> -			op->reg = rd | ((instr & 1) << 5);
> +			op->reg = rd | ((word & 1) << 5);
>  			op->type = MKOP(STORE_VSX, 0, 16);
>  			op->element_size = 1;
>  			op->vsx_flags = VSX_CHECK_VEC;
> @@ -2457,80 +2459,80 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  	case 32:	/* lwz */
>  	case 33:	/* lwzu */
>  		op->type = MKOP(LOAD, u, 4);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 34:	/* lbz */
>  	case 35:	/* lbzu */
>  		op->type = MKOP(LOAD, u, 1);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 36:	/* stw */
>  	case 37:	/* stwu */
>  		op->type = MKOP(STORE, u, 4);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 38:	/* stb */
>  	case 39:	/* stbu */
>  		op->type = MKOP(STORE, u, 1);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 40:	/* lhz */
>  	case 41:	/* lhzu */
>  		op->type = MKOP(LOAD, u, 2);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 42:	/* lha */
>  	case 43:	/* lhau */
>  		op->type = MKOP(LOAD, SIGNEXT | u, 2);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 44:	/* sth */
>  	case 45:	/* sthu */
>  		op->type = MKOP(STORE, u, 2);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 46:	/* lmw */
>  		if (ra >= rd)
>  			break;		/* invalid form, ra in range to load
> */
>  		op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd));
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 47:	/* stmw */
>  		op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd));
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  #ifdef CONFIG_PPC_FPU
>  	case 48:	/* lfs */
>  	case 49:	/* lfsu */
>  		op->type = MKOP(LOAD_FP, u | FPCONV, 4);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 50:	/* lfd */
>  	case 51:	/* lfdu */
>  		op->type = MKOP(LOAD_FP, u, 8);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 52:	/* stfs */
>  	case 53:	/* stfsu */
>  		op->type = MKOP(STORE_FP, u | FPCONV, 4);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  
>  	case 54:	/* stfd */
>  	case 55:	/* stfdu */
>  		op->type = MKOP(STORE_FP, u, 8);
> -		op->ea = dform_ea(instr, regs);
> +		op->ea = dform_ea(word, regs);
>  		break;
>  #endif
>  
> @@ -2538,14 +2540,14 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  	case 56:	/* lq */
>  		if (!((rd & 1) || (rd == ra)))
>  			op->type = MKOP(LOAD, 0, 16);
> -		op->ea = dqform_ea(instr, regs);
> +		op->ea = dqform_ea(word, regs);
>  		break;
>  #endif
>  
>  #ifdef CONFIG_VSX
>  	case 57:	/* lfdp, lxsd, lxssp */
> -		op->ea = dsform_ea(instr, regs);
> -		switch (instr & 3) {
> +		op->ea = dsform_ea(word, regs);
> +		switch (word & 3) {
>  		case 0:		/* lfdp */
>  			if (rd & 1)
>  				break;		/* reg must be even */
> @@ -2569,8 +2571,8 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  #ifdef __powerpc64__
>  	case 58:	/* ld[u], lwa */
> -		op->ea = dsform_ea(instr, regs);
> -		switch (instr & 3) {
> +		op->ea = dsform_ea(word, regs);
> +		switch (word & 3) {
>  		case 0:		/* ld */
>  			op->type = MKOP(LOAD, 0, 8);
>  			break;
> @@ -2586,16 +2588,16 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  #ifdef CONFIG_VSX
>  	case 61:	/* stfdp, lxv, stxsd, stxssp, stxv */
> -		switch (instr & 7) {
> +		switch (word & 7) {
>  		case 0:		/* stfdp with LSB of DS field = 0 */
>  		case 4:		/* stfdp with LSB of DS field = 1 */
> -			op->ea = dsform_ea(instr, regs);
> +			op->ea = dsform_ea(word, regs);
>  			op->type = MKOP(STORE_FP, 0, 16);
>  			break;
>  
>  		case 1:		/* lxv */
> -			op->ea = dqform_ea(instr, regs);
> -			if (instr & 8)
> +			op->ea = dqform_ea(word, regs);
> +			if (word & 8)
>  				op->reg = rd + 32;
>  			op->type = MKOP(LOAD_VSX, 0, 16);
>  			op->element_size = 16;
> @@ -2604,7 +2606,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  		case 2:		/* stxsd with LSB of DS field = 0 */
>  		case 6:		/* stxsd with LSB of DS field = 1 */
> -			op->ea = dsform_ea(instr, regs);
> +			op->ea = dsform_ea(word, regs);
>  			op->reg = rd + 32;
>  			op->type = MKOP(STORE_VSX, 0, 8);
>  			op->element_size = 8;
> @@ -2613,7 +2615,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  		case 3:		/* stxssp with LSB of DS field = 0 */
>  		case 7:		/* stxssp with LSB of DS field = 1 */
> -			op->ea = dsform_ea(instr, regs);
> +			op->ea = dsform_ea(word, regs);
>  			op->reg = rd + 32;
>  			op->type = MKOP(STORE_VSX, 0, 4);
>  			op->element_size = 8;
> @@ -2621,8 +2623,8 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  			break;
>  
>  		case 5:		/* stxv */
> -			op->ea = dqform_ea(instr, regs);
> -			if (instr & 8)
> +			op->ea = dqform_ea(word, regs);
> +			if (word & 8)
>  				op->reg = rd + 32;
>  			op->type = MKOP(STORE_VSX, 0, 16);
>  			op->element_size = 16;
> @@ -2634,8 +2636,8 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  
>  #ifdef __powerpc64__
>  	case 62:	/* std[u] */
> -		op->ea = dsform_ea(instr, regs);
> -		switch (instr & 3) {
> +		op->ea = dsform_ea(word, regs);
> +		switch (word & 3) {
>  		case 0:		/* std */
>  			op->type = MKOP(STORE, 0, 8);
>  			break;
> @@ -2663,7 +2665,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  	return 0;
>  
>   logical_done:
> -	if (instr & 1)
> +	if (word & 1)
>  		set_cr0(regs, op);
>   logical_done_nocc:
>  	op->reg = ra;
> @@ -2671,7 +2673,7 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs,
>  	return 1;
>  
>   arith_done:
> -	if (instr & 1)
> +	if (word & 1)
>  		set_cr0(regs, op);
>   compute_done:
>  	op->reg = rd;
> diff --git a/arch/powerpc/lib/test_emulate_step.c
> b/arch/powerpc/lib/test_emulate_step.c
> index 486e057e5be1..d6275a9b8ce6 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -851,7 +851,7 @@ static int __init emulate_compute_instr(struct pt_regs
> *regs,
>  
>  	if (analyse_instr(&op, regs, instr) != 1 ||
>  	    GETTYPE(op.type) != COMPUTE) {
> -		pr_info("emulation failed, instruction = 0x%08x\n", instr);
> +		pr_info("emulation failed, instruction = 0x%08x\n",
> ppc_inst_word(instr));
>  		return -EFAULT;
>  	}
>  
> @@ -871,7 +871,7 @@ static int __init execute_compute_instr(struct pt_regs
> *regs,
>  	/* Patch the NOP with the actual instruction */
>  	patch_instruction_site(&patch__exec_instr, instr);
>  	if (exec_instr(regs)) {
> -		pr_info("execution failed, instruction = 0x%08x\n", instr);
> +		pr_info("execution failed, instruction = 0x%08x\n",
> ppc_inst_word(instr));
>  		return -EFAULT;
>  	}
>  
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index d045e583f1c9..dec522fa8201 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -2871,9 +2871,9 @@ generic_inst_dump(unsigned long adr, long count, int
> praddr,
>  		dotted = 0;
>  		last_inst = inst;
>  		if (praddr)
> -			printf(REG"  %.8x", adr, inst);
> +			printf(REG"  %.8x", adr, ppc_inst_word(inst));
>  		printf("\t");
> -		dump_func(inst, adr);
> +		dump_func(ppc_inst_word(inst), adr);
>  		printf("\n");
>  	}
>  	return adr - first_adr;


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type
  2020-03-23  7:33   ` Nicholas Piggin
@ 2020-03-23 23:45     ` Jordan Niethe
  2020-03-24  5:40       ` Nicholas Piggin
  0 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-23 23:45 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 6:37 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 20, 2020 3:18 pm:
> > For powerpc64, redefine the ppc_inst type so both word and prefixed
> > instructions can be represented. On powerpc32 the type will remain the
> > same.  Update places which had assumed instructions to be 4 bytes long.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v4: New to series
> > ---
> >  arch/powerpc/include/asm/code-patching.h | 10 +--
> >  arch/powerpc/include/asm/inst.h          | 90 ++++++++++++++++++++++++
> >  arch/powerpc/include/asm/kprobes.h       |  2 +-
> >  arch/powerpc/include/asm/sstep.h         |  4 ++
> >  arch/powerpc/include/asm/uaccess.h       | 22 ++++++
> >  arch/powerpc/include/asm/uprobes.h       |  2 +-
> >  arch/powerpc/kernel/align.c              |  5 +-
> >  arch/powerpc/kernel/hw_breakpoint.c      |  2 +-
> >  arch/powerpc/kernel/kprobes.c            |  7 +-
> >  arch/powerpc/kernel/optprobes.c          | 42 ++++++-----
> >  arch/powerpc/kernel/optprobes_head.S     |  3 +
> >  arch/powerpc/kernel/trace/ftrace.c       | 19 ++++-
> >  arch/powerpc/kernel/uprobes.c            |  2 +-
> >  arch/powerpc/lib/code-patching.c         | 22 ++++--
> >  arch/powerpc/lib/sstep.c                 |  4 +-
> >  arch/powerpc/xmon/xmon.c                 | 38 +++++++---
> >  16 files changed, 221 insertions(+), 53 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
> > index 68bd9db334bd..bd41e1558707 100644
> > --- a/arch/powerpc/include/asm/code-patching.h
> > +++ b/arch/powerpc/include/asm/code-patching.h
> > @@ -25,11 +25,11 @@
> >  bool is_offset_in_branch_range(long offset);
> >  ppc_inst create_branch(const ppc_inst *addr,
> >                          unsigned long target, int flags);
> > -unsigned int create_cond_branch(const ppc_inst *addr,
> > +ppc_inst create_cond_branch(const void *addr,
> >                               unsigned long target, int flags);
> > -int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> > -int patch_instruction(ppc_inst *addr, ppc_inst instr);
> > -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
> > +int patch_branch(void *addr, unsigned long target, int flags);
> > +int patch_instruction(void *addr, ppc_inst instr);
> > +int raw_patch_instruction(void *addr, ppc_inst instr);
> >
> >  static inline unsigned long patch_site_addr(s32 *site)
> >  {
> > @@ -60,7 +60,7 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
> >  int instr_is_relative_branch(ppc_inst instr);
> >  int instr_is_relative_link_branch(ppc_inst instr);
> >  int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> > -unsigned long branch_target(const ppc_inst *instr);
> > +unsigned long branch_target(const void *instr);
> >  ppc_inst translate_branch(const ppc_inst *dest,
> >                             const ppc_inst *src);
> >  extern bool is_conditional_branch(ppc_inst instr);
> > diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> > index 7c8596ee411e..1a40b0a71128 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -6,6 +6,95 @@
> >   * Instruction data type for POWER
> >   */
> >
> > +#ifdef __powerpc64__
> > +
> > +typedef struct ppc_inst {
> > +     union {
> > +             struct {
> > +                     u32 word;
> > +                     u32 pad;
> > +             } __packed;
> > +             struct {
> > +                     u32 prefix;
> > +                     u32 suffix;
> > +             } __packed;
> > +     };
> > +} ppc_inst;
> > +
> > +#define PPC_INST(x) ((ppc_inst) { .word = (x), .pad = 0 })
> > +#define PPC_INST_PREFIXED(x, y) ((ppc_inst) { .prefix = (x), .suffix = (y) })
> > +
> > +static inline int ppc_inst_opcode(ppc_inst x)
> > +{
> > +     return x.word >> 26;
> > +}
> > +
> > +static inline bool ppc_inst_prefixed(ppc_inst x) {
> > +     return ppc_inst_opcode(x) == 1;
> > +}
> > +
> > +static inline int ppc_inst_len(ppc_inst x)
> > +{
> > +     if (ppc_inst_prefixed(x))
> > +             return 8;
> > +     else
> > +             return 4;
> > +}
> > +
> > +static inline u32 ppc_inst_word(ppc_inst x)
> > +{
> > +     return x.word;
> > +}
>
> I guess a concern could be that code using ppc_inst_word could now get a
> prefix unexpectedly and not handle it properly. The reason it should
> generally be okay is that prefix won't match any existing valid
> instruction words, so callers won't match or think it's an unknown
> instruction. Am I right? Possibly a small comment?
Yes all prefixes are illegal as word instructions so I thought that
should be okay.
>
> > +
> > +static inline u32 ppc_inst_prefix(ppc_inst x)
> > +{
> > +     return x.prefix;
> > +}
> > +
> > +static inline u32 ppc_inst_suffix(ppc_inst x)
> > +{
> > +     return x.suffix;
> > +}
> > +
> > +
> > +static inline ppc_inst ppc_inst_read(const void *ptr)
> > +{
> > +     ppc_inst inst;
> > +     inst.word = *(u32 *)ptr;
> > +     if (ppc_inst_prefixed(inst))
> > +             inst.suffix = *((u32 *)ptr + 1);
> > +     else
> > +             inst.pad = 0;
>
> I'm a bit against using partially constructed opaque type for things
> like this, even if it is in the code that knows about the type. We
> could modify ppc_inst_prefixed() to assert that pad is equal to zero
> (or some poisoned value) if it's not prefixed. Or do some validation
> on the suffix if it is.
Okay what about something like:
+static inline ppc_inst ppc_inst_read(const void *ptr)
+{
+     u32 prefix, suffix;
+     prefix = *(u32 *)ptr;
+     if (prefix >> 26 == 1)
+             suffix = *((u32 *)ptr + 1);
+     else
+             suffix = 0;
+     return PPC_INST_PREFIX(prefix, suffix);
+}

>
>
>
> > +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
> > +{
> > +     return !memcmp(&x, &y, sizeof(struct ppc_inst));
> > +}
>
> I guess a variable length memcmp will make terrible code, so you're
> requiring pad to equal 0 to match non-prefixed. Fine.
Yes this assumes pad always gets set to 0.
>
> > +
> > +static inline bool ppc_inst_null(ppc_inst x)
> > +{
> > +     return x.word == 0 && x.pad == 0;
> > +}
>
> In this case you shouldn't need x.pad == 0. If x.word == 0, then
> WARN_ON_ONCE(x.pad != 0) ?
True.
>
> >       if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
> >               /* We don't handle PPC little-endian any more... */
> >               if (cpu_has_feature(CPU_FTR_PPC_LE))
> >                       return -EIO;
> > -             instr = PPC_INST(swab32(ppc_inst_word(instr)));
> > +             instr = PPC_INST_PREFIXED(swab32(ppc_inst_word(instr)),
> > +                                       swab32(ppc_inst_suffix(instr)));
>
> Ugly, don't suppose you'd bother to do a ppc_inst_bswap function for
> this one case?
I can do that.
>
> [snip probes stuff]
>
> > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
> > index fa7f32adf029..3b8277a64b8f 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -24,17 +24,27 @@ static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
> >  {
> >       int err = 0;
> >
> > -     __put_user_asm(instr, patch_addr, err, "stw");
> > +     __put_user_asm(ppc_inst_word(instr), patch_addr, err, "stw");
> >       if (err)
> >               return err;
> >
> >       asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
> >                                                           "r" (exec_addr));
> >
> > +     if (!ppc_inst_prefixed(instr))
> > +             return 0;
> > +
> > +     __put_user_asm(ppc_inst_suffix(instr), patch_addr + 4, err, "stw");
> > +     if (err)
> > +             return err;
> > +
> > +     asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr + 4),
> > +                                                         "r" (exec_addr + 4));
>
> Although there's proably no real performance or atomicity issues here,
> I'd be pleased if we could do a case for prefixed and a case for non
> prefixed, and store the non-prefixed with "std". Just for the principle
> of not having half-written instructions in the image.
Do you mean store the prefixed with std?
>
> You could skip the dcbst and icbi for the second address if you happen
> to know this future CPU does not store prefix insns across a CL
> boundary. But probably not necessary to make that assumption in non
> perf critical code here, so I'd leave it as you have.
>
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index ee084411f2f5..c5536e1a3356 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -110,7 +110,7 @@ struct bpt {
> >  #define BP_DABR              4
> >
> >  #define NBPTS        256
> > -#define BPT_WORDS    2
> > +#define BPT_WORDS    4
>
> (2 * sizeof(ppc_inst) / sizeof(u32)) ?

>
> >  static struct bpt bpts[NBPTS];
> >  static struct bpt dabr;
> >  static struct bpt *iabr;
> > @@ -118,12 +118,13 @@ static unsigned bpinstr = 0x7fe00008;   /* trap */
> >
> >  #define BP_NUM(bp)   ((bp) - bpts + 1)
> >
> > -static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS];
> > +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS] __aligned(64);
>
> Should have a define somewhere for this magical 64.
Sure.
>
> >  /* Prototypes */
> >  static int cmds(struct pt_regs *);
> >  static int mread(unsigned long, void *, int);
> >  static int mwrite(unsigned long, void *, int);
> > +static int mread_instr(unsigned long, ppc_inst *);
>
> In some cases you've addd helpers like this as separate patches,
> others you've bundled them together. NBD but I liked the prep patches
> which then made the more important changes easier to see.
I will make some more prep patches.
>
> > @@ -759,8 +760,8 @@ static int xmon_bpt(struct pt_regs *regs)
> >
> >       /* Are we at the trap at bp->instr[1] for some bp? */
> >       bp = in_breakpoint_table(regs->nip, &offset);
> > -     if (bp != NULL && offset == 4) {
> > -             regs->nip = bp->address + 4;
> > +     if (bp != NULL && (offset == 4 || offset == 8)) {
> > +             regs->nip = bp->address + offset;
> >               atomic_dec(&bp->ref_count);
> >               return 1;
> >       }
> > @@ -862,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
> >       if (off >= sizeof(bpt_table))
> >               return NULL;
> >       bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> > -     if (bp_off != 0 && bp_off != 4)
> > +     if (bp_off != 0 && bp_off != 4 && bp_off != 8)
> >               return NULL;
> >       *offp = bp_off;
> >       return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
> > @@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a)
> >               if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
> >                       bp->address = a;
> >                       bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> > -                     patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
> >                       return bp;
> >               }
> >       }
>
> Why is this okay to remove?
When we only had word instructions the bpt was just patched in here
once and that was that.
With prefixed instructions bp->instr + 1 might be the suffix. So I
moved putting the breakpoint to insert_bpts():
patch_instruction(bp->instr + ppc_inst_len(instr), PPC_INST(bpinstr));
>
> Thanks,
> Nick
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 00/16] Initial Prefixed Instruction support
  2020-03-23 10:17     ` Nicholas Piggin
@ 2020-03-24  2:54       ` Jordan Niethe
  2020-03-24  2:59         ` Jordan Niethe
  2020-03-24  5:44         ` Nicholas Piggin
  0 siblings, 2 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-24  2:54 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 23, 2020 at 9:21 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Jordan Niethe's on March 23, 2020 7:25 pm:
> > On Mon, Mar 23, 2020 at 5:22 PM Nicholas Piggin <npiggin@gmail.com> wrote:
> >>
> >> Jordan Niethe's on March 20, 2020 3:17 pm:
> >> > A future revision of the ISA will introduce prefixed instructions. A
> >> > prefixed instruction is composed of a 4-byte prefix followed by a
> >> > 4-byte suffix.
> >> >
> >> > All prefixes have the major opcode 1. A prefix will never be a valid
> >> > word instruction. A suffix may be an existing word instruction or a
> >> > new instruction.
> >> >
> >> > This series enables prefixed instructions and extends the instruction
> >> > emulation to support them. Then the places where prefixed instructions
> >> > might need to be emulated are updated.
> >> >
> >> > The series is based on top of:
> >> > https://patchwork.ozlabs.org/patch/1232619/ as this will effect
> >> > kprobes.
> >> >
> >> > v4 is based on feedback from Nick Piggins, Christophe Leroy and Daniel Axtens.
> >> > The major changes:
> >> >     - Move xmon breakpoints from data section to text section
> >> >     - Introduce a data type for instructions on powerpc
> >>
> >> Thanks for doing this, looks like a lot of work, I hope it works out :)
> >>
> > Yes it did end up touching a lot of places. I started thinking that
> > that maybe it would be simpler to just use a u64 instead of the struct
> > for  instructions.
> > If we always keep the word instruction / prefix in the lower bytes,
> > all of the current masking should still work and we can use operators
> > again instead of ppc_inst_equal(), etc.
>
> Yeah.. I think now that you've done it, I prefer it this way.
Sorry, just to be clear which way do you mean?
>
> > It also makes printing easier. We could just #define INST_FMT %llx or
> > #define INST_FMT %x on powerpc32 and use that for printing out
> > instructions.
>
> Well, not sure about that. Would it make endian concerns more
> complicated? Print format for prefix might be '%016llx', but we
> don't want that for all instructions only prefixed ones, and I
> don't know if that is the way to go either.
Hm yeah that is true.
>
> We'll want to adopt some convention for displaying prefixed
> instruction bytes, but I don't know what what works best. I wonder
> if binutils or any userspace tools have a convention.
binutils-gdb upstream has supports disassembling prefixed instructions.
Here is what objdump looks like:
  44:    00 00 00 60     nop
  48:    00 00 00 07     pnop
  4c:    00 00 00 00
  50:    01 00 20 39     li      r9,1
  54:    00 00 00 06     paddi   r4,r9,3
  58:    03 00 89 38
  5c:    00 00 62 3c     addis   r3,r2,0
>
> Which reminds me, you might have missed show_instructions()?
> Although maybe you don't need that until we start using them in
> the kernel.
You are right I missed that here.
>
> Thanks,
> Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-23  9:51       ` Nicholas Piggin
@ 2020-03-24  2:58         ` Michael Ellerman
  2020-03-24  3:21           ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Michael Ellerman @ 2020-03-24  2:58 UTC (permalink / raw)
  To: Nicholas Piggin, Jordan Niethe
  Cc: Alistair Popple, Daniel Axtens, linuxppc-dev, Balamuruhan S

Nicholas Piggin <npiggin@gmail.com> writes:
> Jordan Niethe's on March 23, 2020 7:28 pm:
>> On Mon, Mar 23, 2020 at 5:27 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>> Jordan Niethe's on March 20, 2020 3:17 pm:
>>> > Currently unsigned ints are used to represent instructions on powerpc.
>>> > This has worked well as instructions have always been 4 byte words.
>>> > However, a future ISA version will introduce some changes to
>>> > instructions that mean this scheme will no longer work as well. This
>>> > change is Prefixed Instructions. A prefixed instruction is made up of a
>>> > word prefix followed by a word suffix to make an 8 byte double word
>>> > instruction. No matter the endianess of the system the prefix always
>>> > comes first. Prefixed instructions are only planned for powerpc64.
>>> >
>>> > Introduce a ppc_inst type to represent both prefixed and word
>>> > instructions on powerpc64 while keeping it possible to exclusively have
>>> > word instructions on powerpc32, A latter patch will expand the type to
>>> > include prefixed instructions but for now just typedef it to a u32.
>>> >
>>> > Later patches will introduce helper functions and macros for
>>> > manipulating the instructions so that powerpc64 and powerpc32 might
>>> > maintain separate type definitions.
>>>
>>> ppc_inst_t I would slightly prefer for a typedef like this.
>> Are _t types meant to be reserved?
>
> No, just convention that structs are not normally typedefed unless
> they are a pervasive interface that gets passed around a lot but
> does not get accessed without accessor functions much. When you do
> typedef them, add a _t (or less frequently _s/_u/etc). pte_t,
> cpumask_t, atomic_t.

Ideally we wouldn't use a typedef, we'd just have:

struct ppc_inst {
	u32 val;
#ifdef CONFIG_PPC64
        u32 suffix;
#endif
};

That may make the conversion harder though, because you more or less
have to update all usages at once.

cheers

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 00/16] Initial Prefixed Instruction support
  2020-03-24  2:54       ` Jordan Niethe
@ 2020-03-24  2:59         ` Jordan Niethe
  2020-03-24  5:44         ` Nicholas Piggin
  1 sibling, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-24  2:59 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Tue, Mar 24, 2020 at 1:54 PM Jordan Niethe <jniethe5@gmail.com> wrote:
>
> On Mon, Mar 23, 2020 at 9:21 PM Nicholas Piggin <npiggin@gmail.com> wrote:
> >
> > Jordan Niethe's on March 23, 2020 7:25 pm:
> > > On Mon, Mar 23, 2020 at 5:22 PM Nicholas Piggin <npiggin@gmail.com> wrote:
> > >>
> > >> Jordan Niethe's on March 20, 2020 3:17 pm:
> > >> > A future revision of the ISA will introduce prefixed instructions. A
> > >> > prefixed instruction is composed of a 4-byte prefix followed by a
> > >> > 4-byte suffix.
> > >> >
> > >> > All prefixes have the major opcode 1. A prefix will never be a valid
> > >> > word instruction. A suffix may be an existing word instruction or a
> > >> > new instruction.
> > >> >
> > >> > This series enables prefixed instructions and extends the instruction
> > >> > emulation to support them. Then the places where prefixed instructions
> > >> > might need to be emulated are updated.
> > >> >
> > >> > The series is based on top of:
> > >> > https://patchwork.ozlabs.org/patch/1232619/ as this will effect
> > >> > kprobes.
> > >> >
> > >> > v4 is based on feedback from Nick Piggins, Christophe Leroy and Daniel Axtens.
> > >> > The major changes:
> > >> >     - Move xmon breakpoints from data section to text section
> > >> >     - Introduce a data type for instructions on powerpc
> > >>
> > >> Thanks for doing this, looks like a lot of work, I hope it works out :)
> > >>
> > > Yes it did end up touching a lot of places. I started thinking that
> > > that maybe it would be simpler to just use a u64 instead of the struct
> > > for  instructions.
> > > If we always keep the word instruction / prefix in the lower bytes,
> > > all of the current masking should still work and we can use operators
> > > again instead of ppc_inst_equal(), etc.
> >
> > Yeah.. I think now that you've done it, I prefer it this way.
> Sorry, just to be clear which way do you mean?
> >
> > > It also makes printing easier. We could just #define INST_FMT %llx or
> > > #define INST_FMT %x on powerpc32 and use that for printing out
> > > instructions.
> >
> > Well, not sure about that. Would it make endian concerns more
> > complicated? Print format for prefix might be '%016llx', but we
> > don't want that for all instructions only prefixed ones, and I
> > don't know if that is the way to go either.
> Hm yeah that is true.
> >
> > We'll want to adopt some convention for displaying prefixed
> > instruction bytes, but I don't know what what works best. I wonder
> > if binutils or any userspace tools have a convention.
> binutils-gdb upstream has supports disassembling prefixed instructions.
> Here is what objdump looks like:
>   44:    00 00 00 60     nop
>   48:    00 00 00 07     pnop
>   4c:    00 00 00 00
>   50:    01 00 20 39     li      r9,1
>   54:    00 00 00 06     paddi   r4,r9,3
>   58:    03 00 89 38
>   5c:    00 00 62 3c     addis   r3,r2,0
And this is what it looks like if you use objdump with -w
  44:    00 00 00 60     nop
  48:    00 00 00 07 00 00 00 00     pnop
  50:    01 00 20 39                 li      r9,1
  54:    00 00 00 06 03 00 89 38     paddi   r4,r9,3
  5c:    00 00 62 3c                 addis   r3,r2,0    5c:
R_PPC64_TOC16_HA    .toc+0x10

> >
> > Which reminds me, you might have missed show_instructions()?
> > Although maybe you don't need that until we start using them in
> > the kernel.
> You are right I missed that here.
> >
> > Thanks,
> > Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 08/16] powerpc: Use an accessor for word instructions
  2020-03-23 11:12   ` Balamuruhan S
@ 2020-03-24  3:18     ` Jordan Niethe
  2020-03-24  6:22       ` Balamuruhan S
  0 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-03-24  3:18 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Mon, Mar 23, 2020 at 10:13 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Fri, 2020-03-20 at 16:18 +1100, Jordan Niethe wrote:
> > In preparation for prefixed instructions where all instructions are no
> > longer words, use an accessor for getting a word instruction as a u32
> > from the instruction data type.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v4: New to series
> > ---
> >  arch/powerpc/kernel/align.c          |   2 +-
> >  arch/powerpc/kernel/kprobes.c        |   2 +-
> >  arch/powerpc/kernel/trace/ftrace.c   |  16 +-
> >  arch/powerpc/lib/code-patching.c     |   2 +-
> >  arch/powerpc/lib/feature-fixups.c    |   4 +-
> >  arch/powerpc/lib/sstep.c             | 270 ++++++++++++++-------------
> >  arch/powerpc/lib/test_emulate_step.c |   4 +-
> >  arch/powerpc/xmon/xmon.c             |   4 +-
> >  8 files changed, 153 insertions(+), 151 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > index 77c49dfdc1b4..b246ca124931 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -309,7 +309,7 @@ int fix_alignment(struct pt_regs *regs)
> >               /* We don't handle PPC little-endian any more... */
> >               if (cpu_has_feature(CPU_FTR_PPC_LE))
> >                       return -EIO;
> > -             instr = PPC_INST(swab32(instr));
> > +             instr = PPC_INST(swab32(ppc_inst_word(instr)));
> >       }
> >
> >  #ifdef CONFIG_SPE
> > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> > index 4c2b656615a6..0c600b6e4ead 100644
> > --- a/arch/powerpc/kernel/kprobes.c
> > +++ b/arch/powerpc/kernel/kprobes.c
> > @@ -242,7 +242,7 @@ static int try_to_emulate(struct kprobe *p, struct
> > pt_regs *regs)
> >                * So, we should never get here... but, its still
> >                * good to catch them, just in case...
> >                */
> > -             printk("Can't step on instruction %x\n", insn);
> > +             printk("Can't step on instruction %x\n", ppc_inst_word(insn));
> >               BUG();
> >       } else {
> >               /*
> > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > b/arch/powerpc/kernel/trace/ftrace.c
> > index b3645b664819..7614a9f537fd 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -74,7 +74,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst
> > new)
> >       /* Make sure it is what we expect it to be */
> >       if (!ppc_inst_equal(replaced, old)) {
> >               pr_err("%p: replaced (%#x) != old (%#x)",
> > -             (void *)ip, replaced, old);
> > +             (void *)ip, ppc_inst_word(replaced), ppc_inst_word(old));
> >               return -EINVAL;
> >       }
> >
> > @@ -136,7 +136,7 @@ __ftrace_make_nop(struct module *mod,
> >
> >       /* Make sure that that this is still a 24bit jump */
> >       if (!is_bl_op(op)) {
> > -             pr_err("Not expected bl: opcode is %x\n", op);
> > +             pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
> >               return -EINVAL;
> >       }
> >
> > @@ -171,7 +171,7 @@ __ftrace_make_nop(struct module *mod,
> >       /* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
> >       if (!ppc_inst_equal(op, PPC_INST(PPC_INST_MFLR)) &&
> >           !ppc_inst_equal(op, PPC_INST(PPC_INST_STD_LR))) {
> > -             pr_err("Unexpected instruction %08x around bl _mcount\n", op);
> > +             pr_err("Unexpected instruction %08x around bl _mcount\n",
> > ppc_inst_word(op));
> >               return -EINVAL;
> >       }
> >  #else
> > @@ -201,7 +201,7 @@ __ftrace_make_nop(struct module *mod,
> >       }
> >
> >       if (!ppc_inst_equal(op,  PPC_INST(PPC_INST_LD_TOC))) {
> > -             pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op);
> > +             pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC,
> > ppc_inst_word(op));
> >               return -EINVAL;
> >       }
> >  #endif /* CONFIG_MPROFILE_KERNEL */
> > @@ -401,7 +401,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> > *rec, unsigned long addr)
> >
> >       /* Make sure that that this is still a 24bit jump */
> >       if (!is_bl_op(op)) {
> > -             pr_err("Not expected bl: opcode is %x\n", op);
> > +             pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
> >               return -EINVAL;
> >       }
> >
> > @@ -525,7 +525,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> > addr)
> >
> >       if (!expected_nop_sequence(ip, op[0], op[1])) {
> >               pr_err("Unexpected call sequence at %p: %x %x\n",
> > -             ip, op[0], op[1]);
> > +             ip, ppc_inst_word(op[0]), ppc_inst_word(op[1]));
> >               return -EINVAL;
> >       }
> >
> > @@ -644,7 +644,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace
> > *rec, unsigned long addr)
> >       }
> >
> >       if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) {
> > -             pr_err("Unexpected call sequence at %p: %x\n", ip, op);
> > +             pr_err("Unexpected call sequence at %p: %x\n", ip,
> > ppc_inst_word(op));
> >               return -EINVAL;
> >       }
> >
> > @@ -723,7 +723,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> > long old_addr,
> >
> >       /* Make sure that that this is still a 24bit jump */
> >       if (!is_bl_op(op)) {
> > -             pr_err("Not expected bl: opcode is %x\n", op);
> > +             pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op));
> >               return -EINVAL;
> >       }
> >
> > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > patching.c
> > index ec3abe1a6927..849eee63df3d 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -233,7 +233,7 @@ bool is_conditional_branch(ppc_inst instr)
> >       if (opcode == 16)       /* bc, bca, bcl, bcla */
> >               return true;
> >       if (opcode == 19) {
> > -             switch ((instr >> 1) & 0x3ff) {
> > +             switch ((ppc_inst_word(instr) >> 1) & 0x3ff) {
> >               case 16:        /* bclr, bclrl */
> >               case 528:       /* bcctr, bcctrl */
> >               case 560:       /* bctar, bctarl */
> > diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> > fixups.c
> > index 552106d1f64a..fe8ec099aa96 100644
> > --- a/arch/powerpc/lib/feature-fixups.c
> > +++ b/arch/powerpc/lib/feature-fixups.c
> > @@ -54,8 +54,8 @@ static int patch_alt_instruction(unsigned int *src,
> > unsigned int *dest,
> >
> >               /* Branch within the section doesn't need translating */
> >               if (target < alt_start || target > alt_end) {
> > -                     instr = translate_branch(dest, src);
> > -                     if (ppc_inst_null(instr))
> > +                     instr = ppc_inst_word(translate_branch((ppc_inst
> > *)dest, (ppc_inst *)src));
> > +                     if (!instr)
> >                               return 1;
> >               }
> >       }
> > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > index 1d9c766a89fe..bae878a83fa5 100644
> > --- a/arch/powerpc/lib/sstep.c
> > +++ b/arch/powerpc/lib/sstep.c
> > @@ -1169,26 +1169,28 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >       unsigned long int imm;
> >       unsigned long int val, val2;
> >       unsigned int mb, me, sh;
> > +     unsigned int word;
> >       long ival;
> >
> > +     word = ppc_inst_word(instr);
> >       op->type = COMPUTE;
> >
> > -     opcode = instr >> 26;
> > +     opcode = word >> 26;
> >       switch (opcode) {
> >       case 16:        /* bc */
> >               op->type = BRANCH;
> > -             imm = (signed short)(instr & 0xfffc);
> > -             if ((instr & 2) == 0)
> > +             imm = (signed short)(word & 0xfffc);
> > +             if ((word & 2) == 0)
> >                       imm += regs->nip;
> >               op->val = truncate_if_32bit(regs->msr, imm);
> > -             if (instr & 1)
> > +             if (word & 1)
> >                       op->type |= SETLK;
> > -             if (branch_taken(instr, regs, op))
> > +             if (branch_taken(word, regs, op))
> >                       op->type |= BRTAKEN;
> >               return 1;
> >  #ifdef CONFIG_PPC64
> >       case 17:        /* sc */
> > -             if ((instr & 0xfe2) == 2)
> > +             if ((word & 0xfe2) == 2)
> >                       op->type = SYSCALL;
> >               else
> >                       op->type = UNKNOWN;
> > @@ -1196,21 +1198,21 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >  #endif
> >       case 18:        /* b */
> >               op->type = BRANCH | BRTAKEN;
> > -             imm = instr & 0x03fffffc;
> > +             imm = word & 0x03fffffc;
> >               if (imm & 0x02000000)
> >                       imm -= 0x04000000;
> > -             if ((instr & 2) == 0)
> > +             if ((word & 2) == 0)
> >                       imm += regs->nip;
> >               op->val = truncate_if_32bit(regs->msr, imm);
> > -             if (instr & 1)
> > +             if (word & 1)
> >                       op->type |= SETLK;
> >               return 1;
> >       case 19:
> > -             switch ((instr >> 1) & 0x3ff) {
> > +             switch ((word >> 1) & 0x3ff) {
> >               case 0:         /* mcrf */
> >                       op->type = COMPUTE + SETCC;
> > -                     rd = 7 - ((instr >> 23) & 0x7);
> > -                     ra = 7 - ((instr >> 18) & 0x7);
> > +                     rd = 7 - ((word >> 23) & 0x7);
> > +                     ra = 7 - ((word >> 18) & 0x7);
> >                       rd *= 4;
> >                       ra *= 4;
> >                       val = (regs->ccr >> ra) & 0xf;
> > @@ -1220,11 +1222,11 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               case 16:        /* bclr */
> >               case 528:       /* bcctr */
> >                       op->type = BRANCH;
> > -                     imm = (instr & 0x400)? regs->ctr: regs->link;
> > +                     imm = (word & 0x400)? regs->ctr: regs->link;
> >                       op->val = truncate_if_32bit(regs->msr, imm);
> > -                     if (instr & 1)
> > +                     if (word & 1)
> >                               op->type |= SETLK;
> > -                     if (branch_taken(instr, regs, op))
> > +                     if (branch_taken(word, regs, op))
> >                               op->type |= BRTAKEN;
> >                       return 1;
> >
> > @@ -1247,23 +1249,23 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               case 417:       /* crorc */
> >               case 449:       /* cror */
> >                       op->type = COMPUTE + SETCC;
> > -                     ra = (instr >> 16) & 0x1f;
> > -                     rb = (instr >> 11) & 0x1f;
> > -                     rd = (instr >> 21) & 0x1f;
> > +                     ra = (word >> 16) & 0x1f;
> > +                     rb = (word >> 11) & 0x1f;
> > +                     rd = (word >> 21) & 0x1f;
>
> can't we use your accessors for all these operations ?
I felt that since we are doing so many bit operations here it was
simpliest to just leave these as uints.
>
> >                       ra = (regs->ccr >> (31 - ra)) & 1;
> >                       rb = (regs->ccr >> (31 - rb)) & 1;
> > -                     val = (instr >> (6 + ra * 2 + rb)) & 1;
> > +                     val = (word >> (6 + ra * 2 + rb)) & 1;
> >                       op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
> >                               (val << (31 - rd));
> >                       return 1;
> >               }
> >               break;
> >       case 31:
> > -             switch ((instr >> 1) & 0x3ff) {
> > +             switch ((word >> 1) & 0x3ff) {
> >               case 598:       /* sync */
> >                       op->type = BARRIER + BARRIER_SYNC;
> >  #ifdef __powerpc64__
> > -                     switch ((instr >> 21) & 3) {
> > +                     switch ((word >> 21) & 3) {
> >                       case 1:         /* lwsync */
> >                               op->type = BARRIER + BARRIER_LWSYNC;
> >                               break;
> > @@ -1285,20 +1287,20 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >       if (!FULL_REGS(regs))
> >               return -1;
> >
> > -     rd = (instr >> 21) & 0x1f;
> > -     ra = (instr >> 16) & 0x1f;
> > -     rb = (instr >> 11) & 0x1f;
> > -     rc = (instr >> 6) & 0x1f;
> > +     rd = (word >> 21) & 0x1f;
> > +     ra = (word >> 16) & 0x1f;
> > +     rb = (word >> 11) & 0x1f;
> > +     rc = (word >> 6) & 0x1f;
>
> same here and in similar such places.
>
> -- Bala
> >
> >       switch (opcode) {
> >  #ifdef __powerpc64__
> >       case 2:         /* tdi */
> > -             if (rd & trap_compare(regs->gpr[ra], (short) instr))
> > +             if (rd & trap_compare(regs->gpr[ra], (short) word))
> >                       goto trap;
> >               return 1;
> >  #endif
> >       case 3:         /* twi */
> > -             if (rd & trap_compare((int)regs->gpr[ra], (short) instr))
> > +             if (rd & trap_compare((int)regs->gpr[ra], (short) word))
> >                       goto trap;
> >               return 1;
> >
> > @@ -1307,7 +1309,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               if (!cpu_has_feature(CPU_FTR_ARCH_300))
> >                       return -1;
> >
> > -             switch (instr & 0x3f) {
> > +             switch (word & 0x3f) {
> >               case 48:        /* maddhd */
> >                       asm volatile(PPC_MADDHD(%0, %1, %2, %3) :
> >                                    "=r" (op->val) : "r" (regs->gpr[ra]),
> > @@ -1335,16 +1337,16 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >  #endif
> >
> >       case 7:         /* mulli */
> > -             op->val = regs->gpr[ra] * (short) instr;
> > +             op->val = regs->gpr[ra] * (short) word;
> >               goto compute_done;
> >
> >       case 8:         /* subfic */
> > -             imm = (short) instr;
> > +             imm = (short) word;
> >               add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1);
> >               return 1;
> >
> >       case 10:        /* cmpli */
> > -             imm = (unsigned short) instr;
> > +             imm = (unsigned short) word;
> >               val = regs->gpr[ra];
> >  #ifdef __powerpc64__
> >               if ((rd & 1) == 0)
> > @@ -1354,7 +1356,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               return 1;
> >
> >       case 11:        /* cmpi */
> > -             imm = (short) instr;
> > +             imm = (short) word;
> >               val = regs->gpr[ra];
> >  #ifdef __powerpc64__
> >               if ((rd & 1) == 0)
> > @@ -1364,35 +1366,35 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               return 1;
> >
> >       case 12:        /* addic */
> > -             imm = (short) instr;
> > +             imm = (short) word;
> >               add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
> >               return 1;
> >
> >       case 13:        /* addic. */
> > -             imm = (short) instr;
> > +             imm = (short) word;
> >               add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
> >               set_cr0(regs, op);
> >               return 1;
> >
> >       case 14:        /* addi */
> > -             imm = (short) instr;
> > +             imm = (short) word;
> >               if (ra)
> >                       imm += regs->gpr[ra];
> >               op->val = imm;
> >               goto compute_done;
> >
> >       case 15:        /* addis */
> > -             imm = ((short) instr) << 16;
> > +             imm = ((short) word) << 16;
> >               if (ra)
> >                       imm += regs->gpr[ra];
> >               op->val = imm;
> >               goto compute_done;
> >
> >       case 19:
> > -             if (((instr >> 1) & 0x1f) == 2) {
> > +             if (((word >> 1) & 0x1f) == 2) {
> >                       /* addpcis */
> > -                     imm = (short) (instr & 0xffc1); /* d0 + d2 fields */
> > -                     imm |= (instr >> 15) & 0x3e;    /* d1 field */
> > +                     imm = (short) (word & 0xffc1);  /* d0 + d2 fields */
> > +                     imm |= (word >> 15) & 0x3e;     /* d1 field */
> >                       op->val = regs->nip + (imm << 16) + 4;
> >                       goto compute_done;
> >               }
> > @@ -1400,65 +1402,65 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               return 0;
> >
> >       case 20:        /* rlwimi */
> > -             mb = (instr >> 6) & 0x1f;
> > -             me = (instr >> 1) & 0x1f;
> > +             mb = (word >> 6) & 0x1f;
> > +             me = (word >> 1) & 0x1f;
> >               val = DATA32(regs->gpr[rd]);
> >               imm = MASK32(mb, me);
> >               op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm);
> >               goto logical_done;
> >
> >       case 21:        /* rlwinm */
> > -             mb = (instr >> 6) & 0x1f;
> > -             me = (instr >> 1) & 0x1f;
> > +             mb = (word >> 6) & 0x1f;
> > +             me = (word >> 1) & 0x1f;
> >               val = DATA32(regs->gpr[rd]);
> >               op->val = ROTATE(val, rb) & MASK32(mb, me);
> >               goto logical_done;
> >
> >       case 23:        /* rlwnm */
> > -             mb = (instr >> 6) & 0x1f;
> > -             me = (instr >> 1) & 0x1f;
> > +             mb = (word >> 6) & 0x1f;
> > +             me = (word >> 1) & 0x1f;
> >               rb = regs->gpr[rb] & 0x1f;
> >               val = DATA32(regs->gpr[rd]);
> >               op->val = ROTATE(val, rb) & MASK32(mb, me);
> >               goto logical_done;
> >
> >       case 24:        /* ori */
> > -             op->val = regs->gpr[rd] | (unsigned short) instr;
> > +             op->val = regs->gpr[rd] | (unsigned short) word;
> >               goto logical_done_nocc;
> >
> >       case 25:        /* oris */
> > -             imm = (unsigned short) instr;
> > +             imm = (unsigned short) word;
> >               op->val = regs->gpr[rd] | (imm << 16);
> >               goto logical_done_nocc;
> >
> >       case 26:        /* xori */
> > -             op->val = regs->gpr[rd] ^ (unsigned short) instr;
> > +             op->val = regs->gpr[rd] ^ (unsigned short) word;
> >               goto logical_done_nocc;
> >
> >       case 27:        /* xoris */
> > -             imm = (unsigned short) instr;
> > +             imm = (unsigned short) word;
> >               op->val = regs->gpr[rd] ^ (imm << 16);
> >               goto logical_done_nocc;
> >
> >       case 28:        /* andi. */
> > -             op->val = regs->gpr[rd] & (unsigned short) instr;
> > +             op->val = regs->gpr[rd] & (unsigned short) word;
> >               set_cr0(regs, op);
> >               goto logical_done_nocc;
> >
> >       case 29:        /* andis. */
> > -             imm = (unsigned short) instr;
> > +             imm = (unsigned short) word;
> >               op->val = regs->gpr[rd] & (imm << 16);
> >               set_cr0(regs, op);
> >               goto logical_done_nocc;
> >
> >  #ifdef __powerpc64__
> >       case 30:        /* rld* */
> > -             mb = ((instr >> 6) & 0x1f) | (instr & 0x20);
> > +             mb = ((word >> 6) & 0x1f) | (word & 0x20);
> >               val = regs->gpr[rd];
> > -             if ((instr & 0x10) == 0) {
> > -                     sh = rb | ((instr & 2) << 4);
> > +             if ((word & 0x10) == 0) {
> > +                     sh = rb | ((word & 2) << 4);
> >                       val = ROTATE(val, sh);
> > -                     switch ((instr >> 2) & 3) {
> > +                     switch ((word >> 2) & 3) {
> >                       case 0:         /* rldicl */
> >                               val &= MASK64_L(mb);
> >                               break;
> > @@ -1478,7 +1480,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               } else {
> >                       sh = regs->gpr[rb] & 0x3f;
> >                       val = ROTATE(val, sh);
> > -                     switch ((instr >> 1) & 7) {
> > +                     switch ((word >> 1) & 7) {
> >                       case 0:         /* rldcl */
> >                               op->val = val & MASK64_L(mb);
> >                               goto logical_done;
> > @@ -1493,8 +1495,8 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >
> >       case 31:
> >               /* isel occupies 32 minor opcodes */
> > -             if (((instr >> 1) & 0x1f) == 15) {
> > -                     mb = (instr >> 6) & 0x1f; /* bc field */
> > +             if (((word >> 1) & 0x1f) == 15) {
> > +                     mb = (word >> 6) & 0x1f; /* bc field */
> >                       val = (regs->ccr >> (31 - mb)) & 1;
> >                       val2 = (ra) ? regs->gpr[ra] : 0;
> >
> > @@ -1502,7 +1504,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >                       goto compute_done;
> >               }
> >
> > -             switch ((instr >> 1) & 0x3ff) {
> > +             switch ((word >> 1) & 0x3ff) {
> >               case 4:         /* tw */
> >                       if (rd == 0x1f ||
> >                           (rd & trap_compare((int)regs->gpr[ra],
> > @@ -1536,17 +1538,17 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >                       op->reg = rd;
> >                       /* only MSR_EE and MSR_RI get changed if bit 15 set */
> >                       /* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */
> > -                     imm = (instr & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
> > +                     imm = (word & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
> >                       op->val = imm;
> >                       return 0;
> >  #endif
> >
> >               case 19:        /* mfcr */
> >                       imm = 0xffffffffUL;
> > -                     if ((instr >> 20) & 1) {
> > +                     if ((word >> 20) & 1) {
> >                               imm = 0xf0000000UL;
> >                               for (sh = 0; sh < 8; ++sh) {
> > -                                     if (instr & (0x80000 >> sh))
> > +                                     if (word & (0x80000 >> sh))
> >                                               break;
> >                                       imm >>= 4;
> >                               }
> > @@ -1560,7 +1562,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >                       val = regs->gpr[rd];
> >                       op->ccval = regs->ccr;
> >                       for (sh = 0; sh < 8; ++sh) {
> > -                             if (instr & (0x80000 >> sh))
> > +                             if (word & (0x80000 >> sh))
> >                                       op->ccval = (op->ccval & ~imm) |
> >                                               (val & imm);
> >                               imm >>= 4;
> > @@ -1568,7 +1570,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >                       return 1;
> >
> >               case 339:       /* mfspr */
> > -                     spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
> > +                     spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
> >                       op->type = MFSPR;
> >                       op->reg = rd;
> >                       op->spr = spr;
> > @@ -1578,7 +1580,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >                       return 0;
> >
> >               case 467:       /* mtspr */
> > -                     spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
> > +                     spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
> >                       op->type = MTSPR;
> >                       op->val = regs->gpr[rd];
> >                       op->spr = spr;
> > @@ -1948,7 +1950,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               case 826:       /* sradi with sh_5 = 0 */
> >               case 827:       /* sradi with sh_5 = 1 */
> >                       op->type = COMPUTE + SETREG + SETXER;
> > -                     sh = rb | ((instr & 2) << 4);
> > +                     sh = rb | ((word & 2) << 4);
> >                       ival = (signed long int) regs->gpr[rd];
> >                       op->val = ival >> sh;
> >                       op->xerval = regs->xer;
> > @@ -1964,7 +1966,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
> >                               return -1;
> >                       op->type = COMPUTE + SETREG;
> > -                     sh = rb | ((instr & 2) << 4);
> > +                     sh = rb | ((word & 2) << 4);
> >                       val = (signed int) regs->gpr[rd];
> >                       if (sh)
> >                               op->val = ROTATE(val, sh) & MASK64(0, 63 - sh);
> > @@ -1979,34 +1981,34 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >   */
> >               case 54:        /* dcbst */
> >                       op->type = MKOP(CACHEOP, DCBST, 0);
> > -                     op->ea = xform_ea(instr, regs);
> > +                     op->ea = xform_ea(word, regs);
> >                       return 0;
> >
> >               case 86:        /* dcbf */
> >                       op->type = MKOP(CACHEOP, DCBF, 0);
> > -                     op->ea = xform_ea(instr, regs);
> > +                     op->ea = xform_ea(word, regs);
> >                       return 0;
> >
> >               case 246:       /* dcbtst */
> >                       op->type = MKOP(CACHEOP, DCBTST, 0);
> > -                     op->ea = xform_ea(instr, regs);
> > +                     op->ea = xform_ea(word, regs);
> >                       op->reg = rd;
> >                       return 0;
> >
> >               case 278:       /* dcbt */
> >                       op->type = MKOP(CACHEOP, DCBTST, 0);
> > -                     op->ea = xform_ea(instr, regs);
> > +                     op->ea = xform_ea(word, regs);
> >                       op->reg = rd;
> >                       return 0;
> >
> >               case 982:       /* icbi */
> >                       op->type = MKOP(CACHEOP, ICBI, 0);
> > -                     op->ea = xform_ea(instr, regs);
> > +                     op->ea = xform_ea(word, regs);
> >                       return 0;
> >
> >               case 1014:      /* dcbz */
> >                       op->type = MKOP(CACHEOP, DCBZ, 0);
> > -                     op->ea = xform_ea(instr, regs);
> > +                     op->ea = xform_ea(word, regs);
> >                       return 0;
> >               }
> >               break;
> > @@ -2019,14 +2021,14 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >       op->update_reg = ra;
> >       op->reg = rd;
> >       op->val = regs->gpr[rd];
> > -     u = (instr >> 20) & UPDATE;
> > +     u = (word >> 20) & UPDATE;
> >       op->vsx_flags = 0;
> >
> >       switch (opcode) {
> >       case 31:
> > -             u = instr & UPDATE;
> > -             op->ea = xform_ea(instr, regs);
> > -             switch ((instr >> 1) & 0x3ff) {
> > +             u = word & UPDATE;
> > +             op->ea = xform_ea(word, regs);
> > +             switch ((word >> 1) & 0x3ff) {
> >               case 20:        /* lwarx */
> >                       op->type = MKOP(LARX, 0, 4);
> >                       break;
> > @@ -2271,25 +2273,25 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >
> >  #ifdef CONFIG_VSX
> >               case 12:        /* lxsiwzx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 4);
> >                       op->element_size = 8;
> >                       break;
> >
> >               case 76:        /* lxsiwax */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, SIGNEXT, 4);
> >                       op->element_size = 8;
> >                       break;
> >
> >               case 140:       /* stxsiwx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 4);
> >                       op->element_size = 8;
> >                       break;
> >
> >               case 268:       /* lxvx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 16);
> >                       op->element_size = 16;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> > @@ -2298,33 +2300,33 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               case 269:       /* lxvl */
> >               case 301: {     /* lxvll */
> >                       int nb;
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->ea = ra ? regs->gpr[ra] : 0;
> >                       nb = regs->gpr[rb] & 0xff;
> >                       if (nb > 16)
> >                               nb = 16;
> >                       op->type = MKOP(LOAD_VSX, 0, nb);
> >                       op->element_size = 16;
> > -                     op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
> > +                     op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
> >                               VSX_CHECK_VEC;
> >                       break;
> >               }
> >               case 332:       /* lxvdsx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 8);
> >                       op->element_size = 8;
> >                       op->vsx_flags = VSX_SPLAT;
> >                       break;
> >
> >               case 364:       /* lxvwsx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 4);
> >                       op->element_size = 4;
> >                       op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC;
> >                       break;
> >
> >               case 396:       /* stxvx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 16);
> >                       op->element_size = 16;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> > @@ -2333,118 +2335,118 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >               case 397:       /* stxvl */
> >               case 429: {     /* stxvll */
> >                       int nb;
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->ea = ra ? regs->gpr[ra] : 0;
> >                       nb = regs->gpr[rb] & 0xff;
> >                       if (nb > 16)
> >                               nb = 16;
> >                       op->type = MKOP(STORE_VSX, 0, nb);
> >                       op->element_size = 16;
> > -                     op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
> > +                     op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
> >                               VSX_CHECK_VEC;
> >                       break;
> >               }
> >               case 524:       /* lxsspx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 4);
> >                       op->element_size = 8;
> >                       op->vsx_flags = VSX_FPCONV;
> >                       break;
> >
> >               case 588:       /* lxsdx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 8);
> >                       op->element_size = 8;
> >                       break;
> >
> >               case 652:       /* stxsspx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 4);
> >                       op->element_size = 8;
> >                       op->vsx_flags = VSX_FPCONV;
> >                       break;
> >
> >               case 716:       /* stxsdx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 8);
> >                       op->element_size = 8;
> >                       break;
> >
> >               case 780:       /* lxvw4x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 16);
> >                       op->element_size = 4;
> >                       break;
> >
> >               case 781:       /* lxsibzx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 1);
> >                       op->element_size = 8;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> >                       break;
> >
> >               case 812:       /* lxvh8x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 16);
> >                       op->element_size = 2;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> >                       break;
> >
> >               case 813:       /* lxsihzx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 2);
> >                       op->element_size = 8;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> >                       break;
> >
> >               case 844:       /* lxvd2x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 16);
> >                       op->element_size = 8;
> >                       break;
> >
> >               case 876:       /* lxvb16x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(LOAD_VSX, 0, 16);
> >                       op->element_size = 1;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> >                       break;
> >
> >               case 908:       /* stxvw4x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 16);
> >                       op->element_size = 4;
> >                       break;
> >
> >               case 909:       /* stxsibx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 1);
> >                       op->element_size = 8;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> >                       break;
> >
> >               case 940:       /* stxvh8x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 16);
> >                       op->element_size = 2;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> >                       break;
> >
> >               case 941:       /* stxsihx */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 2);
> >                       op->element_size = 8;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> >                       break;
> >
> >               case 972:       /* stxvd2x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 16);
> >                       op->element_size = 8;
> >                       break;
> >
> >               case 1004:      /* stxvb16x */
> > -                     op->reg = rd | ((instr & 1) << 5);
> > +                     op->reg = rd | ((word & 1) << 5);
> >                       op->type = MKOP(STORE_VSX, 0, 16);
> >                       op->element_size = 1;
> >                       op->vsx_flags = VSX_CHECK_VEC;
> > @@ -2457,80 +2459,80 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >       case 32:        /* lwz */
> >       case 33:        /* lwzu */
> >               op->type = MKOP(LOAD, u, 4);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 34:        /* lbz */
> >       case 35:        /* lbzu */
> >               op->type = MKOP(LOAD, u, 1);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 36:        /* stw */
> >       case 37:        /* stwu */
> >               op->type = MKOP(STORE, u, 4);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 38:        /* stb */
> >       case 39:        /* stbu */
> >               op->type = MKOP(STORE, u, 1);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 40:        /* lhz */
> >       case 41:        /* lhzu */
> >               op->type = MKOP(LOAD, u, 2);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 42:        /* lha */
> >       case 43:        /* lhau */
> >               op->type = MKOP(LOAD, SIGNEXT | u, 2);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 44:        /* sth */
> >       case 45:        /* sthu */
> >               op->type = MKOP(STORE, u, 2);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 46:        /* lmw */
> >               if (ra >= rd)
> >                       break;          /* invalid form, ra in range to load
> > */
> >               op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd));
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 47:        /* stmw */
> >               op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd));
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >  #ifdef CONFIG_PPC_FPU
> >       case 48:        /* lfs */
> >       case 49:        /* lfsu */
> >               op->type = MKOP(LOAD_FP, u | FPCONV, 4);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 50:        /* lfd */
> >       case 51:        /* lfdu */
> >               op->type = MKOP(LOAD_FP, u, 8);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 52:        /* stfs */
> >       case 53:        /* stfsu */
> >               op->type = MKOP(STORE_FP, u | FPCONV, 4);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >
> >       case 54:        /* stfd */
> >       case 55:        /* stfdu */
> >               op->type = MKOP(STORE_FP, u, 8);
> > -             op->ea = dform_ea(instr, regs);
> > +             op->ea = dform_ea(word, regs);
> >               break;
> >  #endif
> >
> > @@ -2538,14 +2540,14 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >       case 56:        /* lq */
> >               if (!((rd & 1) || (rd == ra)))
> >                       op->type = MKOP(LOAD, 0, 16);
> > -             op->ea = dqform_ea(instr, regs);
> > +             op->ea = dqform_ea(word, regs);
> >               break;
> >  #endif
> >
> >  #ifdef CONFIG_VSX
> >       case 57:        /* lfdp, lxsd, lxssp */
> > -             op->ea = dsform_ea(instr, regs);
> > -             switch (instr & 3) {
> > +             op->ea = dsform_ea(word, regs);
> > +             switch (word & 3) {
> >               case 0:         /* lfdp */
> >                       if (rd & 1)
> >                               break;          /* reg must be even */
> > @@ -2569,8 +2571,8 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >
> >  #ifdef __powerpc64__
> >       case 58:        /* ld[u], lwa */
> > -             op->ea = dsform_ea(instr, regs);
> > -             switch (instr & 3) {
> > +             op->ea = dsform_ea(word, regs);
> > +             switch (word & 3) {
> >               case 0:         /* ld */
> >                       op->type = MKOP(LOAD, 0, 8);
> >                       break;
> > @@ -2586,16 +2588,16 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >
> >  #ifdef CONFIG_VSX
> >       case 61:        /* stfdp, lxv, stxsd, stxssp, stxv */
> > -             switch (instr & 7) {
> > +             switch (word & 7) {
> >               case 0:         /* stfdp with LSB of DS field = 0 */
> >               case 4:         /* stfdp with LSB of DS field = 1 */
> > -                     op->ea = dsform_ea(instr, regs);
> > +                     op->ea = dsform_ea(word, regs);
> >                       op->type = MKOP(STORE_FP, 0, 16);
> >                       break;
> >
> >               case 1:         /* lxv */
> > -                     op->ea = dqform_ea(instr, regs);
> > -                     if (instr & 8)
> > +                     op->ea = dqform_ea(word, regs);
> > +                     if (word & 8)
> >                               op->reg = rd + 32;
> >                       op->type = MKOP(LOAD_VSX, 0, 16);
> >                       op->element_size = 16;
> > @@ -2604,7 +2606,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >
> >               case 2:         /* stxsd with LSB of DS field = 0 */
> >               case 6:         /* stxsd with LSB of DS field = 1 */
> > -                     op->ea = dsform_ea(instr, regs);
> > +                     op->ea = dsform_ea(word, regs);
> >                       op->reg = rd + 32;
> >                       op->type = MKOP(STORE_VSX, 0, 8);
> >                       op->element_size = 8;
> > @@ -2613,7 +2615,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >
> >               case 3:         /* stxssp with LSB of DS field = 0 */
> >               case 7:         /* stxssp with LSB of DS field = 1 */
> > -                     op->ea = dsform_ea(instr, regs);
> > +                     op->ea = dsform_ea(word, regs);
> >                       op->reg = rd + 32;
> >                       op->type = MKOP(STORE_VSX, 0, 4);
> >                       op->element_size = 8;
> > @@ -2621,8 +2623,8 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >                       break;
> >
> >               case 5:         /* stxv */
> > -                     op->ea = dqform_ea(instr, regs);
> > -                     if (instr & 8)
> > +                     op->ea = dqform_ea(word, regs);
> > +                     if (word & 8)
> >                               op->reg = rd + 32;
> >                       op->type = MKOP(STORE_VSX, 0, 16);
> >                       op->element_size = 16;
> > @@ -2634,8 +2636,8 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >
> >  #ifdef __powerpc64__
> >       case 62:        /* std[u] */
> > -             op->ea = dsform_ea(instr, regs);
> > -             switch (instr & 3) {
> > +             op->ea = dsform_ea(word, regs);
> > +             switch (word & 3) {
> >               case 0:         /* std */
> >                       op->type = MKOP(STORE, 0, 8);
> >                       break;
> > @@ -2663,7 +2665,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >       return 0;
> >
> >   logical_done:
> > -     if (instr & 1)
> > +     if (word & 1)
> >               set_cr0(regs, op);
> >   logical_done_nocc:
> >       op->reg = ra;
> > @@ -2671,7 +2673,7 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs,
> >       return 1;
> >
> >   arith_done:
> > -     if (instr & 1)
> > +     if (word & 1)
> >               set_cr0(regs, op);
> >   compute_done:
> >       op->reg = rd;
> > diff --git a/arch/powerpc/lib/test_emulate_step.c
> > b/arch/powerpc/lib/test_emulate_step.c
> > index 486e057e5be1..d6275a9b8ce6 100644
> > --- a/arch/powerpc/lib/test_emulate_step.c
> > +++ b/arch/powerpc/lib/test_emulate_step.c
> > @@ -851,7 +851,7 @@ static int __init emulate_compute_instr(struct pt_regs
> > *regs,
> >
> >       if (analyse_instr(&op, regs, instr) != 1 ||
> >           GETTYPE(op.type) != COMPUTE) {
> > -             pr_info("emulation failed, instruction = 0x%08x\n", instr);
> > +             pr_info("emulation failed, instruction = 0x%08x\n",
> > ppc_inst_word(instr));
> >               return -EFAULT;
> >       }
> >
> > @@ -871,7 +871,7 @@ static int __init execute_compute_instr(struct pt_regs
> > *regs,
> >       /* Patch the NOP with the actual instruction */
> >       patch_instruction_site(&patch__exec_instr, instr);
> >       if (exec_instr(regs)) {
> > -             pr_info("execution failed, instruction = 0x%08x\n", instr);
> > +             pr_info("execution failed, instruction = 0x%08x\n",
> > ppc_inst_word(instr));
> >               return -EFAULT;
> >       }
> >
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index d045e583f1c9..dec522fa8201 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -2871,9 +2871,9 @@ generic_inst_dump(unsigned long adr, long count, int
> > praddr,
> >               dotted = 0;
> >               last_inst = inst;
> >               if (praddr)
> > -                     printf(REG"  %.8x", adr, inst);
> > +                     printf(REG"  %.8x", adr, ppc_inst_word(inst));
> >               printf("\t");
> > -             dump_func(inst, adr);
> > +             dump_func(ppc_inst_word(inst), adr);
> >               printf("\n");
> >       }
> >       return adr - first_adr;
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-24  2:58         ` Michael Ellerman
@ 2020-03-24  3:21           ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-24  3:21 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Alistair Popple, Nicholas Piggin, Balamuruhan S, linuxppc-dev,
	Daniel Axtens

On Tue, Mar 24, 2020 at 1:58 PM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Nicholas Piggin <npiggin@gmail.com> writes:
> > Jordan Niethe's on March 23, 2020 7:28 pm:
> >> On Mon, Mar 23, 2020 at 5:27 PM Nicholas Piggin <npiggin@gmail.com> wrote:
> >>> Jordan Niethe's on March 20, 2020 3:17 pm:
> >>> > Currently unsigned ints are used to represent instructions on powerpc.
> >>> > This has worked well as instructions have always been 4 byte words.
> >>> > However, a future ISA version will introduce some changes to
> >>> > instructions that mean this scheme will no longer work as well. This
> >>> > change is Prefixed Instructions. A prefixed instruction is made up of a
> >>> > word prefix followed by a word suffix to make an 8 byte double word
> >>> > instruction. No matter the endianess of the system the prefix always
> >>> > comes first. Prefixed instructions are only planned for powerpc64.
> >>> >
> >>> > Introduce a ppc_inst type to represent both prefixed and word
> >>> > instructions on powerpc64 while keeping it possible to exclusively have
> >>> > word instructions on powerpc32, A latter patch will expand the type to
> >>> > include prefixed instructions but for now just typedef it to a u32.
> >>> >
> >>> > Later patches will introduce helper functions and macros for
> >>> > manipulating the instructions so that powerpc64 and powerpc32 might
> >>> > maintain separate type definitions.
> >>>
> >>> ppc_inst_t I would slightly prefer for a typedef like this.
> >> Are _t types meant to be reserved?
> >
> > No, just convention that structs are not normally typedefed unless
> > they are a pervasive interface that gets passed around a lot but
> > does not get accessed without accessor functions much. When you do
> > typedef them, add a _t (or less frequently _s/_u/etc). pte_t,
> > cpumask_t, atomic_t.
>
> Ideally we wouldn't use a typedef, we'd just have:
>
> struct ppc_inst {
>         u32 val;
> #ifdef CONFIG_PPC64
>         u32 suffix;
> #endif
> };
>
> That may make the conversion harder though, because you more or less
> have to update all usages at once.
Okay I will give that a try.
>
> cheers

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type
  2020-03-23 23:45     ` Jordan Niethe
@ 2020-03-24  5:40       ` Nicholas Piggin
  0 siblings, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-24  5:40 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

Jordan Niethe's on March 24, 2020 9:45 am:
> On Mon, Mar 23, 2020 at 6:37 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Jordan Niethe's on March 20, 2020 3:18 pm:
>> I'm a bit against using partially constructed opaque type for things
>> like this, even if it is in the code that knows about the type. We
>> could modify ppc_inst_prefixed() to assert that pad is equal to zero
>> (or some poisoned value) if it's not prefixed. Or do some validation
>> on the suffix if it is.
> Okay what about something like:
> +static inline ppc_inst ppc_inst_read(const void *ptr)
> +{
> +     u32 prefix, suffix;
> +     prefix = *(u32 *)ptr;
> +     if (prefix >> 26 == 1)
> +             suffix = *((u32 *)ptr + 1);
> +     else
> +             suffix = 0;
> +     return PPC_INST_PREFIX(prefix, suffix);
> +}

Sure, if that's the best way to test prefix.

>> Although there's proably no real performance or atomicity issues here,
>> I'd be pleased if we could do a case for prefixed and a case for non
>> prefixed, and store the non-prefixed with "std". Just for the principle
>> of not having half-written instructions in the image.
> Do you mean store the prefixed with std?

Oops, yes.

>> > @@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a)
>> >               if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
>> >                       bp->address = a;
>> >                       bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
>> > -                     patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
>> >                       return bp;
>> >               }
>> >       }
>>
>> Why is this okay to remove?
> When we only had word instructions the bpt was just patched in here
> once and that was that.
> With prefixed instructions bp->instr + 1 might be the suffix. So I
> moved putting the breakpoint to insert_bpts():
> patch_instruction(bp->instr + ppc_inst_len(instr), PPC_INST(bpinstr));

Ah okay.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 00/16] Initial Prefixed Instruction support
  2020-03-24  2:54       ` Jordan Niethe
  2020-03-24  2:59         ` Jordan Niethe
@ 2020-03-24  5:44         ` Nicholas Piggin
  1 sibling, 0 replies; 65+ messages in thread
From: Nicholas Piggin @ 2020-03-24  5:44 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: Alistair Popple, Balamuruhan S, linuxppc-dev, Daniel Axtens

Jordan Niethe's on March 24, 2020 12:54 pm:
> On Mon, Mar 23, 2020 at 9:21 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Jordan Niethe's on March 23, 2020 7:25 pm:
>> > On Mon, Mar 23, 2020 at 5:22 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>> >>
>> >> Jordan Niethe's on March 20, 2020 3:17 pm:
>> >> > A future revision of the ISA will introduce prefixed instructions. A
>> >> > prefixed instruction is composed of a 4-byte prefix followed by a
>> >> > 4-byte suffix.
>> >> >
>> >> > All prefixes have the major opcode 1. A prefix will never be a valid
>> >> > word instruction. A suffix may be an existing word instruction or a
>> >> > new instruction.
>> >> >
>> >> > This series enables prefixed instructions and extends the instruction
>> >> > emulation to support them. Then the places where prefixed instructions
>> >> > might need to be emulated are updated.
>> >> >
>> >> > The series is based on top of:
>> >> > https://patchwork.ozlabs.org/patch/1232619/ as this will effect
>> >> > kprobes.
>> >> >
>> >> > v4 is based on feedback from Nick Piggins, Christophe Leroy and Daniel Axtens.
>> >> > The major changes:
>> >> >     - Move xmon breakpoints from data section to text section
>> >> >     - Introduce a data type for instructions on powerpc
>> >>
>> >> Thanks for doing this, looks like a lot of work, I hope it works out :)
>> >>
>> > Yes it did end up touching a lot of places. I started thinking that
>> > that maybe it would be simpler to just use a u64 instead of the struct
>> > for  instructions.
>> > If we always keep the word instruction / prefix in the lower bytes,
>> > all of the current masking should still work and we can use operators
>> > again instead of ppc_inst_equal(), etc.
>>
>> Yeah.. I think now that you've done it, I prefer it this way.
> Sorry, just to be clear which way do you mean?

With the struct, not u64 scalar. mpe's preferred way is fine by me.

>> We'll want to adopt some convention for displaying prefixed
>> instruction bytes, but I don't know what what works best. I wonder
>> if binutils or any userspace tools have a convention.
> binutils-gdb upstream has supports disassembling prefixed instructions.
> Here is what objdump looks like:
>   44:    00 00 00 60     nop
>   48:    00 00 00 07     pnop
>   4c:    00 00 00 00
>   50:    01 00 20 39     li      r9,1
>   54:    00 00 00 06     paddi   r4,r9,3
>   58:    03 00 89 38
>   5c:    00 00 62 3c     addis   r3,r2,0
>>
>> Which reminds me, you might have missed show_instructions()?
>> Although maybe you don't need that until we start using them in
>> the kernel.
> You are right I missed that here.

So binutils doesn't do anything special, I guess you can make something
up.

Thanks,
Nick

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 08/16] powerpc: Use an accessor for word instructions
  2020-03-24  3:18     ` Jordan Niethe
@ 2020-03-24  6:22       ` Balamuruhan S
  0 siblings, 0 replies; 65+ messages in thread
From: Balamuruhan S @ 2020-03-24  6:22 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Tue, 2020-03-24 at 14:18 +1100, Jordan Niethe wrote:
> On Mon, Mar 23, 2020 at 10:13 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
> > On Fri, 2020-03-20 at 16:18 +1100, Jordan Niethe wrote:
> > > In preparation for prefixed instructions where all instructions are no
> > > longer words, use an accessor for getting a word instruction as a u32
> > > from the instruction data type.
> > > 
> > > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > > ---
> > > v4: New to series
> > > ---
> > >  arch/powerpc/kernel/align.c          |   2 +-
> > >  arch/powerpc/kernel/kprobes.c        |   2 +-
> > >  arch/powerpc/kernel/trace/ftrace.c   |  16 +-
> > >  arch/powerpc/lib/code-patching.c     |   2 +-
> > >  arch/powerpc/lib/feature-fixups.c    |   4 +-
> > >  arch/powerpc/lib/sstep.c             | 270 ++++++++++++++-------------
> > >  arch/powerpc/lib/test_emulate_step.c |   4 +-
> > >  arch/powerpc/xmon/xmon.c             |   4 +-
> > >  8 files changed, 153 insertions(+), 151 deletions(-)
> > > 
> > > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > > index 77c49dfdc1b4..b246ca124931 100644
> > > --- a/arch/powerpc/kernel/align.c
> > > +++ b/arch/powerpc/kernel/align.c
> > > @@ -309,7 +309,7 @@ int fix_alignment(struct pt_regs *regs)
> > >               /* We don't handle PPC little-endian any more... */
> > >               if (cpu_has_feature(CPU_FTR_PPC_LE))
> > >                       return -EIO;
> > > -             instr = PPC_INST(swab32(instr));
> > > +             instr = PPC_INST(swab32(ppc_inst_word(instr)));
> > >       }
> > > 
> > >  #ifdef CONFIG_SPE
> > > diff --git a/arch/powerpc/kernel/kprobes.c
> > > b/arch/powerpc/kernel/kprobes.c
> > > index 4c2b656615a6..0c600b6e4ead 100644
> > > --- a/arch/powerpc/kernel/kprobes.c
> > > +++ b/arch/powerpc/kernel/kprobes.c
> > > @@ -242,7 +242,7 @@ static int try_to_emulate(struct kprobe *p, struct
> > > pt_regs *regs)
> > >                * So, we should never get here... but, its still
> > >                * good to catch them, just in case...
> > >                */
> > > -             printk("Can't step on instruction %x\n", insn);
> > > +             printk("Can't step on instruction %x\n",
> > > ppc_inst_word(insn));
> > >               BUG();
> > >       } else {
> > >               /*
> > > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > > b/arch/powerpc/kernel/trace/ftrace.c
> > > index b3645b664819..7614a9f537fd 100644
> > > --- a/arch/powerpc/kernel/trace/ftrace.c
> > > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > > @@ -74,7 +74,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old,
> > > ppc_inst
> > > new)
> > >       /* Make sure it is what we expect it to be */
> > >       if (!ppc_inst_equal(replaced, old)) {
> > >               pr_err("%p: replaced (%#x) != old (%#x)",
> > > -             (void *)ip, replaced, old);
> > > +             (void *)ip, ppc_inst_word(replaced), ppc_inst_word(old));
> > >               return -EINVAL;
> > >       }
> > > 
> > > @@ -136,7 +136,7 @@ __ftrace_make_nop(struct module *mod,
> > > 
> > >       /* Make sure that that this is still a 24bit jump */
> > >       if (!is_bl_op(op)) {
> > > -             pr_err("Not expected bl: opcode is %x\n", op);
> > > +             pr_err("Not expected bl: opcode is %x\n",
> > > ppc_inst_word(op));
> > >               return -EINVAL;
> > >       }
> > > 
> > > @@ -171,7 +171,7 @@ __ftrace_make_nop(struct module *mod,
> > >       /* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
> > >       if (!ppc_inst_equal(op, PPC_INST(PPC_INST_MFLR)) &&
> > >           !ppc_inst_equal(op, PPC_INST(PPC_INST_STD_LR))) {
> > > -             pr_err("Unexpected instruction %08x around bl _mcount\n",
> > > op);
> > > +             pr_err("Unexpected instruction %08x around bl _mcount\n",
> > > ppc_inst_word(op));
> > >               return -EINVAL;
> > >       }
> > >  #else
> > > @@ -201,7 +201,7 @@ __ftrace_make_nop(struct module *mod,
> > >       }
> > > 
> > >       if (!ppc_inst_equal(op,  PPC_INST(PPC_INST_LD_TOC))) {
> > > -             pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op);
> > > +             pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC,
> > > ppc_inst_word(op));
> > >               return -EINVAL;
> > >       }
> > >  #endif /* CONFIG_MPROFILE_KERNEL */
> > > @@ -401,7 +401,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> > > *rec, unsigned long addr)
> > > 
> > >       /* Make sure that that this is still a 24bit jump */
> > >       if (!is_bl_op(op)) {
> > > -             pr_err("Not expected bl: opcode is %x\n", op);
> > > +             pr_err("Not expected bl: opcode is %x\n",
> > > ppc_inst_word(op));
> > >               return -EINVAL;
> > >       }
> > > 
> > > @@ -525,7 +525,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > long
> > > addr)
> > > 
> > >       if (!expected_nop_sequence(ip, op[0], op[1])) {
> > >               pr_err("Unexpected call sequence at %p: %x %x\n",
> > > -             ip, op[0], op[1]);
> > > +             ip, ppc_inst_word(op[0]), ppc_inst_word(op[1]));
> > >               return -EINVAL;
> > >       }
> > > 
> > > @@ -644,7 +644,7 @@ static int __ftrace_make_call_kernel(struct
> > > dyn_ftrace
> > > *rec, unsigned long addr)
> > >       }
> > > 
> > >       if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) {
> > > -             pr_err("Unexpected call sequence at %p: %x\n", ip, op);
> > > +             pr_err("Unexpected call sequence at %p: %x\n", ip,
> > > ppc_inst_word(op));
> > >               return -EINVAL;
> > >       }
> > > 
> > > @@ -723,7 +723,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> > > long old_addr,
> > > 
> > >       /* Make sure that that this is still a 24bit jump */
> > >       if (!is_bl_op(op)) {
> > > -             pr_err("Not expected bl: opcode is %x\n", op);
> > > +             pr_err("Not expected bl: opcode is %x\n",
> > > ppc_inst_word(op));
> > >               return -EINVAL;
> > >       }
> > > 
> > > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > > patching.c
> > > index ec3abe1a6927..849eee63df3d 100644
> > > --- a/arch/powerpc/lib/code-patching.c
> > > +++ b/arch/powerpc/lib/code-patching.c
> > > @@ -233,7 +233,7 @@ bool is_conditional_branch(ppc_inst instr)
> > >       if (opcode == 16)       /* bc, bca, bcl, bcla */
> > >               return true;
> > >       if (opcode == 19) {
> > > -             switch ((instr >> 1) & 0x3ff) {
> > > +             switch ((ppc_inst_word(instr) >> 1) & 0x3ff) {
> > >               case 16:        /* bclr, bclrl */
> > >               case 528:       /* bcctr, bcctrl */
> > >               case 560:       /* bctar, bctarl */
> > > diff --git a/arch/powerpc/lib/feature-fixups.c
> > > b/arch/powerpc/lib/feature-
> > > fixups.c
> > > index 552106d1f64a..fe8ec099aa96 100644
> > > --- a/arch/powerpc/lib/feature-fixups.c
> > > +++ b/arch/powerpc/lib/feature-fixups.c
> > > @@ -54,8 +54,8 @@ static int patch_alt_instruction(unsigned int *src,
> > > unsigned int *dest,
> > > 
> > >               /* Branch within the section doesn't need translating */
> > >               if (target < alt_start || target > alt_end) {
> > > -                     instr = translate_branch(dest, src);
> > > -                     if (ppc_inst_null(instr))
> > > +                     instr = ppc_inst_word(translate_branch((ppc_inst
> > > *)dest, (ppc_inst *)src));
> > > +                     if (!instr)
> > >                               return 1;
> > >               }
> > >       }
> > > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > > index 1d9c766a89fe..bae878a83fa5 100644
> > > --- a/arch/powerpc/lib/sstep.c
> > > +++ b/arch/powerpc/lib/sstep.c
> > > @@ -1169,26 +1169,28 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >       unsigned long int imm;
> > >       unsigned long int val, val2;
> > >       unsigned int mb, me, sh;
> > > +     unsigned int word;
> > >       long ival;
> > > 
> > > +     word = ppc_inst_word(instr);
> > >       op->type = COMPUTE;
> > > 
> > > -     opcode = instr >> 26;
> > > +     opcode = word >> 26;
> > >       switch (opcode) {
> > >       case 16:        /* bc */
> > >               op->type = BRANCH;
> > > -             imm = (signed short)(instr & 0xfffc);
> > > -             if ((instr & 2) == 0)
> > > +             imm = (signed short)(word & 0xfffc);
> > > +             if ((word & 2) == 0)
> > >                       imm += regs->nip;
> > >               op->val = truncate_if_32bit(regs->msr, imm);
> > > -             if (instr & 1)
> > > +             if (word & 1)
> > >                       op->type |= SETLK;
> > > -             if (branch_taken(instr, regs, op))
> > > +             if (branch_taken(word, regs, op))
> > >                       op->type |= BRTAKEN;
> > >               return 1;
> > >  #ifdef CONFIG_PPC64
> > >       case 17:        /* sc */
> > > -             if ((instr & 0xfe2) == 2)
> > > +             if ((word & 0xfe2) == 2)
> > >                       op->type = SYSCALL;
> > >               else
> > >                       op->type = UNKNOWN;
> > > @@ -1196,21 +1198,21 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >  #endif
> > >       case 18:        /* b */
> > >               op->type = BRANCH | BRTAKEN;
> > > -             imm = instr & 0x03fffffc;
> > > +             imm = word & 0x03fffffc;
> > >               if (imm & 0x02000000)
> > >                       imm -= 0x04000000;
> > > -             if ((instr & 2) == 0)
> > > +             if ((word & 2) == 0)
> > >                       imm += regs->nip;
> > >               op->val = truncate_if_32bit(regs->msr, imm);
> > > -             if (instr & 1)
> > > +             if (word & 1)
> > >                       op->type |= SETLK;
> > >               return 1;
> > >       case 19:
> > > -             switch ((instr >> 1) & 0x3ff) {
> > > +             switch ((word >> 1) & 0x3ff) {
> > >               case 0:         /* mcrf */
> > >                       op->type = COMPUTE + SETCC;
> > > -                     rd = 7 - ((instr >> 23) & 0x7);
> > > -                     ra = 7 - ((instr >> 18) & 0x7);
> > > +                     rd = 7 - ((word >> 23) & 0x7);
> > > +                     ra = 7 - ((word >> 18) & 0x7);
> > >                       rd *= 4;
> > >                       ra *= 4;
> > >                       val = (regs->ccr >> ra) & 0xf;
> > > @@ -1220,11 +1222,11 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >               case 16:        /* bclr */
> > >               case 528:       /* bcctr */
> > >                       op->type = BRANCH;
> > > -                     imm = (instr & 0x400)? regs->ctr: regs->link;
> > > +                     imm = (word & 0x400)? regs->ctr: regs->link;
> > >                       op->val = truncate_if_32bit(regs->msr, imm);
> > > -                     if (instr & 1)
> > > +                     if (word & 1)
> > >                               op->type |= SETLK;
> > > -                     if (branch_taken(instr, regs, op))
> > > +                     if (branch_taken(word, regs, op))
> > >                               op->type |= BRTAKEN;
> > >                       return 1;
> > > 
> > > @@ -1247,23 +1249,23 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >               case 417:       /* crorc */
> > >               case 449:       /* cror */
> > >                       op->type = COMPUTE + SETCC;
> > > -                     ra = (instr >> 16) & 0x1f;
> > > -                     rb = (instr >> 11) & 0x1f;
> > > -                     rd = (instr >> 21) & 0x1f;
> > > +                     ra = (word >> 16) & 0x1f;
> > > +                     rb = (word >> 11) & 0x1f;
> > > +                     rd = (word >> 21) & 0x1f;
> > 
> > can't we use your accessors for all these operations ?
> I felt that since we are doing so many bit operations here it was
> simpliest to just leave these as uints.

Okay :+1:

-- Bala
> > >                       ra = (regs->ccr >> (31 - ra)) & 1;
> > >                       rb = (regs->ccr >> (31 - rb)) & 1;
> > > -                     val = (instr >> (6 + ra * 2 + rb)) & 1;
> > > +                     val = (word >> (6 + ra * 2 + rb)) & 1;
> > >                       op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
> > >                               (val << (31 - rd));
> > >                       return 1;
> > >               }
> > >               break;
> > >       case 31:
> > > -             switch ((instr >> 1) & 0x3ff) {
> > > +             switch ((word >> 1) & 0x3ff) {
> > >               case 598:       /* sync */
> > >                       op->type = BARRIER + BARRIER_SYNC;
> > >  #ifdef __powerpc64__
> > > -                     switch ((instr >> 21) & 3) {
> > > +                     switch ((word >> 21) & 3) {
> > >                       case 1:         /* lwsync */
> > >                               op->type = BARRIER + BARRIER_LWSYNC;
> > >                               break;
> > > @@ -1285,20 +1287,20 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >       if (!FULL_REGS(regs))
> > >               return -1;
> > > 
> > > -     rd = (instr >> 21) & 0x1f;
> > > -     ra = (instr >> 16) & 0x1f;
> > > -     rb = (instr >> 11) & 0x1f;
> > > -     rc = (instr >> 6) & 0x1f;
> > > +     rd = (word >> 21) & 0x1f;
> > > +     ra = (word >> 16) & 0x1f;
> > > +     rb = (word >> 11) & 0x1f;
> > > +     rc = (word >> 6) & 0x1f;
> > 
> > same here and in similar such places.
> > 
> > -- Bala
> > >       switch (opcode) {
> > >  #ifdef __powerpc64__
> > >       case 2:         /* tdi */
> > > -             if (rd & trap_compare(regs->gpr[ra], (short) instr))
> > > +             if (rd & trap_compare(regs->gpr[ra], (short) word))
> > >                       goto trap;
> > >               return 1;
> > >  #endif
> > >       case 3:         /* twi */
> > > -             if (rd & trap_compare((int)regs->gpr[ra], (short) instr))
> > > +             if (rd & trap_compare((int)regs->gpr[ra], (short) word))
> > >                       goto trap;
> > >               return 1;
> > > 
> > > @@ -1307,7 +1309,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >               if (!cpu_has_feature(CPU_FTR_ARCH_300))
> > >                       return -1;
> > > 
> > > -             switch (instr & 0x3f) {
> > > +             switch (word & 0x3f) {
> > >               case 48:        /* maddhd */
> > >                       asm volatile(PPC_MADDHD(%0, %1, %2, %3) :
> > >                                    "=r" (op->val) : "r" (regs->gpr[ra]),
> > > @@ -1335,16 +1337,16 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >  #endif
> > > 
> > >       case 7:         /* mulli */
> > > -             op->val = regs->gpr[ra] * (short) instr;
> > > +             op->val = regs->gpr[ra] * (short) word;
> > >               goto compute_done;
> > > 
> > >       case 8:         /* subfic */
> > > -             imm = (short) instr;
> > > +             imm = (short) word;
> > >               add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1);
> > >               return 1;
> > > 
> > >       case 10:        /* cmpli */
> > > -             imm = (unsigned short) instr;
> > > +             imm = (unsigned short) word;
> > >               val = regs->gpr[ra];
> > >  #ifdef __powerpc64__
> > >               if ((rd & 1) == 0)
> > > @@ -1354,7 +1356,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >               return 1;
> > > 
> > >       case 11:        /* cmpi */
> > > -             imm = (short) instr;
> > > +             imm = (short) word;
> > >               val = regs->gpr[ra];
> > >  #ifdef __powerpc64__
> > >               if ((rd & 1) == 0)
> > > @@ -1364,35 +1366,35 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >               return 1;
> > > 
> > >       case 12:        /* addic */
> > > -             imm = (short) instr;
> > > +             imm = (short) word;
> > >               add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
> > >               return 1;
> > > 
> > >       case 13:        /* addic. */
> > > -             imm = (short) instr;
> > > +             imm = (short) word;
> > >               add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
> > >               set_cr0(regs, op);
> > >               return 1;
> > > 
> > >       case 14:        /* addi */
> > > -             imm = (short) instr;
> > > +             imm = (short) word;
> > >               if (ra)
> > >                       imm += regs->gpr[ra];
> > >               op->val = imm;
> > >               goto compute_done;
> > > 
> > >       case 15:        /* addis */
> > > -             imm = ((short) instr) << 16;
> > > +             imm = ((short) word) << 16;
> > >               if (ra)
> > >                       imm += regs->gpr[ra];
> > >               op->val = imm;
> > >               goto compute_done;
> > > 
> > >       case 19:
> > > -             if (((instr >> 1) & 0x1f) == 2) {
> > > +             if (((word >> 1) & 0x1f) == 2) {
> > >                       /* addpcis */
> > > -                     imm = (short) (instr & 0xffc1); /* d0 + d2 fields
> > > */
> > > -                     imm |= (instr >> 15) & 0x3e;    /* d1 field */
> > > +                     imm = (short) (word & 0xffc1);  /* d0 + d2 fields
> > > */
> > > +                     imm |= (word >> 15) & 0x3e;     /* d1 field */
> > >                       op->val = regs->nip + (imm << 16) + 4;
> > >                       goto compute_done;
> > >               }
> > > @@ -1400,65 +1402,65 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >               return 0;
> > > 
> > >       case 20:        /* rlwimi */
> > > -             mb = (instr >> 6) & 0x1f;
> > > -             me = (instr >> 1) & 0x1f;
> > > +             mb = (word >> 6) & 0x1f;
> > > +             me = (word >> 1) & 0x1f;
> > >               val = DATA32(regs->gpr[rd]);
> > >               imm = MASK32(mb, me);
> > >               op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm);
> > >               goto logical_done;
> > > 
> > >       case 21:        /* rlwinm */
> > > -             mb = (instr >> 6) & 0x1f;
> > > -             me = (instr >> 1) & 0x1f;
> > > +             mb = (word >> 6) & 0x1f;
> > > +             me = (word >> 1) & 0x1f;
> > >               val = DATA32(regs->gpr[rd]);
> > >               op->val = ROTATE(val, rb) & MASK32(mb, me);
> > >               goto logical_done;
> > > 
> > >       case 23:        /* rlwnm */
> > > -             mb = (instr >> 6) & 0x1f;
> > > -             me = (instr >> 1) & 0x1f;
> > > +             mb = (word >> 6) & 0x1f;
> > > +             me = (word >> 1) & 0x1f;
> > >               rb = regs->gpr[rb] & 0x1f;
> > >               val = DATA32(regs->gpr[rd]);
> > >               op->val = ROTATE(val, rb) & MASK32(mb, me);
> > >               goto logical_done;
> > > 
> > >       case 24:        /* ori */
> > > -             op->val = regs->gpr[rd] | (unsigned short) instr;
> > > +             op->val = regs->gpr[rd] | (unsigned short) word;
> > >               goto logical_done_nocc;
> > > 
> > >       case 25:        /* oris */
> > > -             imm = (unsigned short) instr;
> > > +             imm = (unsigned short) word;
> > >               op->val = regs->gpr[rd] | (imm << 16);
> > >               goto logical_done_nocc;
> > > 
> > >       case 26:        /* xori */
> > > -             op->val = regs->gpr[rd] ^ (unsigned short) instr;
> > > +             op->val = regs->gpr[rd] ^ (unsigned short) word;
> > >               goto logical_done_nocc;
> > > 
> > >       case 27:        /* xoris */
> > > -             imm = (unsigned short) instr;
> > > +             imm = (unsigned short) word;
> > >               op->val = regs->gpr[rd] ^ (imm << 16);
> > >               goto logical_done_nocc;
> > > 
> > >       case 28:        /* andi. */
> > > -             op->val = regs->gpr[rd] & (unsigned short) instr;
> > > +             op->val = regs->gpr[rd] & (unsigned short) word;
> > >               set_cr0(regs, op);
> > >               goto logical_done_nocc;
> > > 
> > >       case 29:        /* andis. */
> > > -             imm = (unsigned short) instr;
> > > +             imm = (unsigned short) word;
> > >               op->val = regs->gpr[rd] & (imm << 16);
> > >               set_cr0(regs, op);
> > >               goto logical_done_nocc;
> > > 
> > >  #ifdef __powerpc64__
> > >       case 30:        /* rld* */
> > > -             mb = ((instr >> 6) & 0x1f) | (instr & 0x20);
> > > +             mb = ((word >> 6) & 0x1f) | (word & 0x20);
> > >               val = regs->gpr[rd];
> > > -             if ((instr & 0x10) == 0) {
> > > -                     sh = rb | ((instr & 2) << 4);
> > > +             if ((word & 0x10) == 0) {
> > > +                     sh = rb | ((word & 2) << 4);
> > >                       val = ROTATE(val, sh);
> > > -                     switch ((instr >> 2) & 3) {
> > > +                     switch ((word >> 2) & 3) {
> > >                       case 0:         /* rldicl */
> > >                               val &= MASK64_L(mb);
> > >                               break;
> > > @@ -1478,7 +1480,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >               } else {
> > >                       sh = regs->gpr[rb] & 0x3f;
> > >                       val = ROTATE(val, sh);
> > > -                     switch ((instr >> 1) & 7) {
> > > +                     switch ((word >> 1) & 7) {
> > >                       case 0:         /* rldcl */
> > >                               op->val = val & MASK64_L(mb);
> > >                               goto logical_done;
> > > @@ -1493,8 +1495,8 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > > 
> > >       case 31:
> > >               /* isel occupies 32 minor opcodes */
> > > -             if (((instr >> 1) & 0x1f) == 15) {
> > > -                     mb = (instr >> 6) & 0x1f; /* bc field */
> > > +             if (((word >> 1) & 0x1f) == 15) {
> > > +                     mb = (word >> 6) & 0x1f; /* bc field */
> > >                       val = (regs->ccr >> (31 - mb)) & 1;
> > >                       val2 = (ra) ? regs->gpr[ra] : 0;
> > > 
> > > @@ -1502,7 +1504,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >                       goto compute_done;
> > >               }
> > > 
> > > -             switch ((instr >> 1) & 0x3ff) {
> > > +             switch ((word >> 1) & 0x3ff) {
> > >               case 4:         /* tw */
> > >                       if (rd == 0x1f ||
> > >                           (rd & trap_compare((int)regs->gpr[ra],
> > > @@ -1536,17 +1538,17 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >                       op->reg = rd;
> > >                       /* only MSR_EE and MSR_RI get changed if bit 15 set
> > > */
> > >                       /* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE
> > > */
> > > -                     imm = (instr & 0x10000)? 0x8002:
> > > 0xefffffffffffeffeUL;
> > > +                     imm = (word & 0x10000)? 0x8002:
> > > 0xefffffffffffeffeUL;
> > >                       op->val = imm;
> > >                       return 0;
> > >  #endif
> > > 
> > >               case 19:        /* mfcr */
> > >                       imm = 0xffffffffUL;
> > > -                     if ((instr >> 20) & 1) {
> > > +                     if ((word >> 20) & 1) {
> > >                               imm = 0xf0000000UL;
> > >                               for (sh = 0; sh < 8; ++sh) {
> > > -                                     if (instr & (0x80000 >> sh))
> > > +                                     if (word & (0x80000 >> sh))
> > >                                               break;
> > >                                       imm >>= 4;
> > >                               }
> > > @@ -1560,7 +1562,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >                       val = regs->gpr[rd];
> > >                       op->ccval = regs->ccr;
> > >                       for (sh = 0; sh < 8; ++sh) {
> > > -                             if (instr & (0x80000 >> sh))
> > > +                             if (word & (0x80000 >> sh))
> > >                                       op->ccval = (op->ccval & ~imm) |
> > >                                               (val & imm);
> > >                               imm >>= 4;
> > > @@ -1568,7 +1570,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >                       return 1;
> > > 
> > >               case 339:       /* mfspr */
> > > -                     spr = ((instr >> 16) & 0x1f) | ((instr >> 6) &
> > > 0x3e0);
> > > +                     spr = ((word >> 16) & 0x1f) | ((word >> 6) &
> > > 0x3e0);
> > >                       op->type = MFSPR;
> > >                       op->reg = rd;
> > >                       op->spr = spr;
> > > @@ -1578,7 +1580,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >                       return 0;
> > > 
> > >               case 467:       /* mtspr */
> > > -                     spr = ((instr >> 16) & 0x1f) | ((instr >> 6) &
> > > 0x3e0);
> > > +                     spr = ((word >> 16) & 0x1f) | ((word >> 6) &
> > > 0x3e0);
> > >                       op->type = MTSPR;
> > >                       op->val = regs->gpr[rd];
> > >                       op->spr = spr;
> > > @@ -1948,7 +1950,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >               case 826:       /* sradi with sh_5 = 0 */
> > >               case 827:       /* sradi with sh_5 = 1 */
> > >                       op->type = COMPUTE + SETREG + SETXER;
> > > -                     sh = rb | ((instr & 2) << 4);
> > > +                     sh = rb | ((word & 2) << 4);
> > >                       ival = (signed long int) regs->gpr[rd];
> > >                       op->val = ival >> sh;
> > >                       op->xerval = regs->xer;
> > > @@ -1964,7 +1966,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
> > >                               return -1;
> > >                       op->type = COMPUTE + SETREG;
> > > -                     sh = rb | ((instr & 2) << 4);
> > > +                     sh = rb | ((word & 2) << 4);
> > >                       val = (signed int) regs->gpr[rd];
> > >                       if (sh)
> > >                               op->val = ROTATE(val, sh) & MASK64(0, 63 -
> > > sh);
> > > @@ -1979,34 +1981,34 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >   */
> > >               case 54:        /* dcbst */
> > >                       op->type = MKOP(CACHEOP, DCBST, 0);
> > > -                     op->ea = xform_ea(instr, regs);
> > > +                     op->ea = xform_ea(word, regs);
> > >                       return 0;
> > > 
> > >               case 86:        /* dcbf */
> > >                       op->type = MKOP(CACHEOP, DCBF, 0);
> > > -                     op->ea = xform_ea(instr, regs);
> > > +                     op->ea = xform_ea(word, regs);
> > >                       return 0;
> > > 
> > >               case 246:       /* dcbtst */
> > >                       op->type = MKOP(CACHEOP, DCBTST, 0);
> > > -                     op->ea = xform_ea(instr, regs);
> > > +                     op->ea = xform_ea(word, regs);
> > >                       op->reg = rd;
> > >                       return 0;
> > > 
> > >               case 278:       /* dcbt */
> > >                       op->type = MKOP(CACHEOP, DCBTST, 0);
> > > -                     op->ea = xform_ea(instr, regs);
> > > +                     op->ea = xform_ea(word, regs);
> > >                       op->reg = rd;
> > >                       return 0;
> > > 
> > >               case 982:       /* icbi */
> > >                       op->type = MKOP(CACHEOP, ICBI, 0);
> > > -                     op->ea = xform_ea(instr, regs);
> > > +                     op->ea = xform_ea(word, regs);
> > >                       return 0;
> > > 
> > >               case 1014:      /* dcbz */
> > >                       op->type = MKOP(CACHEOP, DCBZ, 0);
> > > -                     op->ea = xform_ea(instr, regs);
> > > +                     op->ea = xform_ea(word, regs);
> > >                       return 0;
> > >               }
> > >               break;
> > > @@ -2019,14 +2021,14 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >       op->update_reg = ra;
> > >       op->reg = rd;
> > >       op->val = regs->gpr[rd];
> > > -     u = (instr >> 20) & UPDATE;
> > > +     u = (word >> 20) & UPDATE;
> > >       op->vsx_flags = 0;
> > > 
> > >       switch (opcode) {
> > >       case 31:
> > > -             u = instr & UPDATE;
> > > -             op->ea = xform_ea(instr, regs);
> > > -             switch ((instr >> 1) & 0x3ff) {
> > > +             u = word & UPDATE;
> > > +             op->ea = xform_ea(word, regs);
> > > +             switch ((word >> 1) & 0x3ff) {
> > >               case 20:        /* lwarx */
> > >                       op->type = MKOP(LARX, 0, 4);
> > >                       break;
> > > @@ -2271,25 +2273,25 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > > 
> > >  #ifdef CONFIG_VSX
> > >               case 12:        /* lxsiwzx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 4);
> > >                       op->element_size = 8;
> > >                       break;
> > > 
> > >               case 76:        /* lxsiwax */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, SIGNEXT, 4);
> > >                       op->element_size = 8;
> > >                       break;
> > > 
> > >               case 140:       /* stxsiwx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 4);
> > >                       op->element_size = 8;
> > >                       break;
> > > 
> > >               case 268:       /* lxvx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 16);
> > >                       op->element_size = 16;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > > @@ -2298,33 +2300,33 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >               case 269:       /* lxvl */
> > >               case 301: {     /* lxvll */
> > >                       int nb;
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->ea = ra ? regs->gpr[ra] : 0;
> > >                       nb = regs->gpr[rb] & 0xff;
> > >                       if (nb > 16)
> > >                               nb = 16;
> > >                       op->type = MKOP(LOAD_VSX, 0, nb);
> > >                       op->element_size = 16;
> > > -                     op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
> > > +                     op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
> > >                               VSX_CHECK_VEC;
> > >                       break;
> > >               }
> > >               case 332:       /* lxvdsx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 8);
> > >                       op->element_size = 8;
> > >                       op->vsx_flags = VSX_SPLAT;
> > >                       break;
> > > 
> > >               case 364:       /* lxvwsx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 4);
> > >                       op->element_size = 4;
> > >                       op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 396:       /* stxvx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 16);
> > >                       op->element_size = 16;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > > @@ -2333,118 +2335,118 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >               case 397:       /* stxvl */
> > >               case 429: {     /* stxvll */
> > >                       int nb;
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->ea = ra ? regs->gpr[ra] : 0;
> > >                       nb = regs->gpr[rb] & 0xff;
> > >                       if (nb > 16)
> > >                               nb = 16;
> > >                       op->type = MKOP(STORE_VSX, 0, nb);
> > >                       op->element_size = 16;
> > > -                     op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
> > > +                     op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
> > >                               VSX_CHECK_VEC;
> > >                       break;
> > >               }
> > >               case 524:       /* lxsspx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 4);
> > >                       op->element_size = 8;
> > >                       op->vsx_flags = VSX_FPCONV;
> > >                       break;
> > > 
> > >               case 588:       /* lxsdx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 8);
> > >                       op->element_size = 8;
> > >                       break;
> > > 
> > >               case 652:       /* stxsspx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 4);
> > >                       op->element_size = 8;
> > >                       op->vsx_flags = VSX_FPCONV;
> > >                       break;
> > > 
> > >               case 716:       /* stxsdx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 8);
> > >                       op->element_size = 8;
> > >                       break;
> > > 
> > >               case 780:       /* lxvw4x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 16);
> > >                       op->element_size = 4;
> > >                       break;
> > > 
> > >               case 781:       /* lxsibzx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 1);
> > >                       op->element_size = 8;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 812:       /* lxvh8x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 16);
> > >                       op->element_size = 2;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 813:       /* lxsihzx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 2);
> > >                       op->element_size = 8;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 844:       /* lxvd2x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 16);
> > >                       op->element_size = 8;
> > >                       break;
> > > 
> > >               case 876:       /* lxvb16x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(LOAD_VSX, 0, 16);
> > >                       op->element_size = 1;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 908:       /* stxvw4x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 16);
> > >                       op->element_size = 4;
> > >                       break;
> > > 
> > >               case 909:       /* stxsibx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 1);
> > >                       op->element_size = 8;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 940:       /* stxvh8x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 16);
> > >                       op->element_size = 2;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 941:       /* stxsihx */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 2);
> > >                       op->element_size = 8;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > >                       break;
> > > 
> > >               case 972:       /* stxvd2x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 16);
> > >                       op->element_size = 8;
> > >                       break;
> > > 
> > >               case 1004:      /* stxvb16x */
> > > -                     op->reg = rd | ((instr & 1) << 5);
> > > +                     op->reg = rd | ((word & 1) << 5);
> > >                       op->type = MKOP(STORE_VSX, 0, 16);
> > >                       op->element_size = 1;
> > >                       op->vsx_flags = VSX_CHECK_VEC;
> > > @@ -2457,80 +2459,80 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >       case 32:        /* lwz */
> > >       case 33:        /* lwzu */
> > >               op->type = MKOP(LOAD, u, 4);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 34:        /* lbz */
> > >       case 35:        /* lbzu */
> > >               op->type = MKOP(LOAD, u, 1);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 36:        /* stw */
> > >       case 37:        /* stwu */
> > >               op->type = MKOP(STORE, u, 4);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 38:        /* stb */
> > >       case 39:        /* stbu */
> > >               op->type = MKOP(STORE, u, 1);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 40:        /* lhz */
> > >       case 41:        /* lhzu */
> > >               op->type = MKOP(LOAD, u, 2);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 42:        /* lha */
> > >       case 43:        /* lhau */
> > >               op->type = MKOP(LOAD, SIGNEXT | u, 2);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 44:        /* sth */
> > >       case 45:        /* sthu */
> > >               op->type = MKOP(STORE, u, 2);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 46:        /* lmw */
> > >               if (ra >= rd)
> > >                       break;          /* invalid form, ra in range to
> > > load
> > > */
> > >               op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd));
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 47:        /* stmw */
> > >               op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd));
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >  #ifdef CONFIG_PPC_FPU
> > >       case 48:        /* lfs */
> > >       case 49:        /* lfsu */
> > >               op->type = MKOP(LOAD_FP, u | FPCONV, 4);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 50:        /* lfd */
> > >       case 51:        /* lfdu */
> > >               op->type = MKOP(LOAD_FP, u, 8);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 52:        /* stfs */
> > >       case 53:        /* stfsu */
> > >               op->type = MKOP(STORE_FP, u | FPCONV, 4);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > > 
> > >       case 54:        /* stfd */
> > >       case 55:        /* stfdu */
> > >               op->type = MKOP(STORE_FP, u, 8);
> > > -             op->ea = dform_ea(instr, regs);
> > > +             op->ea = dform_ea(word, regs);
> > >               break;
> > >  #endif
> > > 
> > > @@ -2538,14 +2540,14 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > >       case 56:        /* lq */
> > >               if (!((rd & 1) || (rd == ra)))
> > >                       op->type = MKOP(LOAD, 0, 16);
> > > -             op->ea = dqform_ea(instr, regs);
> > > +             op->ea = dqform_ea(word, regs);
> > >               break;
> > >  #endif
> > > 
> > >  #ifdef CONFIG_VSX
> > >       case 57:        /* lfdp, lxsd, lxssp */
> > > -             op->ea = dsform_ea(instr, regs);
> > > -             switch (instr & 3) {
> > > +             op->ea = dsform_ea(word, regs);
> > > +             switch (word & 3) {
> > >               case 0:         /* lfdp */
> > >                       if (rd & 1)
> > >                               break;          /* reg must be even */
> > > @@ -2569,8 +2571,8 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > > 
> > >  #ifdef __powerpc64__
> > >       case 58:        /* ld[u], lwa */
> > > -             op->ea = dsform_ea(instr, regs);
> > > -             switch (instr & 3) {
> > > +             op->ea = dsform_ea(word, regs);
> > > +             switch (word & 3) {
> > >               case 0:         /* ld */
> > >                       op->type = MKOP(LOAD, 0, 8);
> > >                       break;
> > > @@ -2586,16 +2588,16 @@ int analyse_instr(struct instruction_op *op,
> > > const
> > > struct pt_regs *regs,
> > > 
> > >  #ifdef CONFIG_VSX
> > >       case 61:        /* stfdp, lxv, stxsd, stxssp, stxv */
> > > -             switch (instr & 7) {
> > > +             switch (word & 7) {
> > >               case 0:         /* stfdp with LSB of DS field = 0 */
> > >               case 4:         /* stfdp with LSB of DS field = 1 */
> > > -                     op->ea = dsform_ea(instr, regs);
> > > +                     op->ea = dsform_ea(word, regs);
> > >                       op->type = MKOP(STORE_FP, 0, 16);
> > >                       break;
> > > 
> > >               case 1:         /* lxv */
> > > -                     op->ea = dqform_ea(instr, regs);
> > > -                     if (instr & 8)
> > > +                     op->ea = dqform_ea(word, regs);
> > > +                     if (word & 8)
> > >                               op->reg = rd + 32;
> > >                       op->type = MKOP(LOAD_VSX, 0, 16);
> > >                       op->element_size = 16;
> > > @@ -2604,7 +2606,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > > 
> > >               case 2:         /* stxsd with LSB of DS field = 0 */
> > >               case 6:         /* stxsd with LSB of DS field = 1 */
> > > -                     op->ea = dsform_ea(instr, regs);
> > > +                     op->ea = dsform_ea(word, regs);
> > >                       op->reg = rd + 32;
> > >                       op->type = MKOP(STORE_VSX, 0, 8);
> > >                       op->element_size = 8;
> > > @@ -2613,7 +2615,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > > 
> > >               case 3:         /* stxssp with LSB of DS field = 0 */
> > >               case 7:         /* stxssp with LSB of DS field = 1 */
> > > -                     op->ea = dsform_ea(instr, regs);
> > > +                     op->ea = dsform_ea(word, regs);
> > >                       op->reg = rd + 32;
> > >                       op->type = MKOP(STORE_VSX, 0, 4);
> > >                       op->element_size = 8;
> > > @@ -2621,8 +2623,8 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >                       break;
> > > 
> > >               case 5:         /* stxv */
> > > -                     op->ea = dqform_ea(instr, regs);
> > > -                     if (instr & 8)
> > > +                     op->ea = dqform_ea(word, regs);
> > > +                     if (word & 8)
> > >                               op->reg = rd + 32;
> > >                       op->type = MKOP(STORE_VSX, 0, 16);
> > >                       op->element_size = 16;
> > > @@ -2634,8 +2636,8 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > > 
> > >  #ifdef __powerpc64__
> > >       case 62:        /* std[u] */
> > > -             op->ea = dsform_ea(instr, regs);
> > > -             switch (instr & 3) {
> > > +             op->ea = dsform_ea(word, regs);
> > > +             switch (word & 3) {
> > >               case 0:         /* std */
> > >                       op->type = MKOP(STORE, 0, 8);
> > >                       break;
> > > @@ -2663,7 +2665,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >       return 0;
> > > 
> > >   logical_done:
> > > -     if (instr & 1)
> > > +     if (word & 1)
> > >               set_cr0(regs, op);
> > >   logical_done_nocc:
> > >       op->reg = ra;
> > > @@ -2671,7 +2673,7 @@ int analyse_instr(struct instruction_op *op, const
> > > struct pt_regs *regs,
> > >       return 1;
> > > 
> > >   arith_done:
> > > -     if (instr & 1)
> > > +     if (word & 1)
> > >               set_cr0(regs, op);
> > >   compute_done:
> > >       op->reg = rd;
> > > diff --git a/arch/powerpc/lib/test_emulate_step.c
> > > b/arch/powerpc/lib/test_emulate_step.c
> > > index 486e057e5be1..d6275a9b8ce6 100644
> > > --- a/arch/powerpc/lib/test_emulate_step.c
> > > +++ b/arch/powerpc/lib/test_emulate_step.c
> > > @@ -851,7 +851,7 @@ static int __init emulate_compute_instr(struct
> > > pt_regs
> > > *regs,
> > > 
> > >       if (analyse_instr(&op, regs, instr) != 1 ||
> > >           GETTYPE(op.type) != COMPUTE) {
> > > -             pr_info("emulation failed, instruction = 0x%08x\n", instr);
> > > +             pr_info("emulation failed, instruction = 0x%08x\n",
> > > ppc_inst_word(instr));
> > >               return -EFAULT;
> > >       }
> > > 
> > > @@ -871,7 +871,7 @@ static int __init execute_compute_instr(struct
> > > pt_regs
> > > *regs,
> > >       /* Patch the NOP with the actual instruction */
> > >       patch_instruction_site(&patch__exec_instr, instr);
> > >       if (exec_instr(regs)) {
> > > -             pr_info("execution failed, instruction = 0x%08x\n", instr);
> > > +             pr_info("execution failed, instruction = 0x%08x\n",
> > > ppc_inst_word(instr));
> > >               return -EFAULT;
> > >       }
> > > 
> > > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > > index d045e583f1c9..dec522fa8201 100644
> > > --- a/arch/powerpc/xmon/xmon.c
> > > +++ b/arch/powerpc/xmon/xmon.c
> > > @@ -2871,9 +2871,9 @@ generic_inst_dump(unsigned long adr, long count,
> > > int
> > > praddr,
> > >               dotted = 0;
> > >               last_inst = inst;
> > >               if (praddr)
> > > -                     printf(REG"  %.8x", adr, inst);
> > > +                     printf(REG"  %.8x", adr, ppc_inst_word(inst));
> > >               printf("\t");
> > > -             dump_func(inst, adr);
> > > +             dump_func(ppc_inst_word(inst), adr);
> > >               printf("\n");
> > >       }
> > >       return adr - first_adr;


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type
  2020-03-20  5:18 ` [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
  2020-03-23  6:58   ` Nicholas Piggin
  2020-03-23  7:33   ` Nicholas Piggin
@ 2020-03-30  9:05   ` Alistair Popple
  2020-03-30  9:13     ` Jordan Niethe
  2 siblings, 1 reply; 65+ messages in thread
From: Alistair Popple @ 2020-03-30  9:05 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: npiggin, bala24, linuxppc-dev, dja

<snip>

> @@ -487,12 +487,13 @@ int kprobe_post_handler(struct pt_regs *regs)
>  {
>  	struct kprobe *cur = kprobe_running();
>  	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +	int len = ppc_inst_len(ppc_inst_read(cur->ainsn.insn));

I am no kprobes expert but it seems based on the code here that in some 
circumstances it's ok/expected that cur == NULL, therefore the assignment 
needs to happen after the check below to avoid dereferencing NULL. At least 
this was the problem I was hitting when running some of the kernel selftests.

- Alistair
 
>  	if (!cur || user_mode(regs))
>  		return 0;
> 
>  	/* 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) {
> @@ -501,7 +502,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/optprobes.c
> b/arch/powerpc/kernel/optprobes.c index 5b53c373373b..af6761859fba 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -158,38 +158,38 @@ void patch_imm32_load_insns(unsigned int val,
> kprobe_opcode_t *addr)
> 
>  /*
>   * Generate instructions to load provided immediate 64-bit value
> - * to register 'r3' and patch these instructions at 'addr'.
> + * to register 'reg' and patch these instructions at 'addr'.
>   */
> -void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
> +void patch_imm64_load_insns(unsigned long val, int reg, kprobe_opcode_t
> *addr) {
> -	/* lis r3,(op)@highest */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(3) |
> +	/* lis reg,(op)@highest */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(reg) |
>  			  ((val >> 48) & 0xffff)));
>  	addr++;
> 
> -	/* ori r3,r3,(op)@higher */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | ((val >> 32) & 0xffff)));
> +	/* ori reg,reg,(op)@higher */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
>  	addr++;
> 
> -	/* rldicr r3,r3,32,31 */
> -	patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)));
> +	/* rldicr reg,reg,32,31 */
> +	patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | __PPC_SH64(32) | __PPC_ME64(31)));
>  	addr++;
> 
> -	/* oris r3,r3,(op)@h */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | ((val >> 16) & 0xffff)));
> +	/* oris reg,reg,(op)@h */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
>  	addr++;
> 
> -	/* ori r3,r3,(op)@l */
> -	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
> -			  ___PPC_RS(3) | (val & 0xffff)));
> +	/* ori reg,reg,(op)@l */
> +	patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | (val & 0xffff)));
>  }
> 
>  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct
> kprobe *p) {
> -	ppc_inst branch_op_callback, branch_emulate_step;
> +	ppc_inst branch_op_callback, branch_emulate_step, temp;
>  	kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
>  	long b_offset;
>  	unsigned long nip, size;
> @@ -239,7 +239,7 @@ int arch_prepare_optimized_kprobe(struct
> optimized_kprobe *op, struct kprobe *p) * Fixup the template with
> instructions to:
>  	 * 1. load the address of the actual probepoint
>  	 */
> -	patch_imm64_load_insns((unsigned long)op, buff + TMPL_OP_IDX);
> +	patch_imm64_load_insns((unsigned long)op, 3, buff + TMPL_OP_IDX);
> 
>  	/*
>  	 * 2. branch to optimized_callback() and emulate_step()
> @@ -268,7 +268,11 @@ int arch_prepare_optimized_kprobe(struct
> optimized_kprobe *op, struct kprobe *p) /*
>  	 * 3. load instruction to be emulated into relevant register, and
>  	 */
> -	patch_imm32_load_insns(*(unsigned int *)p->ainsn.insn, buff +
> TMPL_INSN_IDX); +	temp = ppc_inst_read(p->ainsn.insn);
> +	patch_imm64_load_insns(ppc_inst_word(temp) |
> +			       ((u64)ppc_inst_suffix(temp) << 32),
> +			       4,
> +			       buff + TMPL_INSN_IDX);
> 
>  	/*
>  	 * 4. branch back from trampoline
> diff --git a/arch/powerpc/kernel/optprobes_head.S
> b/arch/powerpc/kernel/optprobes_head.S index cf383520843f..ff8ba4d3824d
> 100644
> --- a/arch/powerpc/kernel/optprobes_head.S
> +++ b/arch/powerpc/kernel/optprobes_head.S
> @@ -94,6 +94,9 @@ optprobe_template_insn:
>  	/* 2, Pass instruction to be emulated in r4 */
>  	nop
>  	nop
> +	nop
> +	nop
> +	nop
> 
>  	.global optprobe_template_call_emulate
>  optprobe_template_call_emulate:
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c index ad451205f268..3b8655f57b4a
> 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -42,9 +42,24 @@
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> 
>  static long
> -read_inst(ppc_inst *inst, const void *src)
> +read_inst(ppc_inst *p, const void *src)
>  {
> -	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> +	ppc_inst inst;
> +	long err;
> +
> +	err = probe_kernel_read((void *)&inst.prefix,
> +				src, MCOUNT_INSN_SIZE);
> +	if (err)
> +		return err;
> +
> +	if (ppc_inst_prefixed(inst))
> +		err = probe_kernel_read((void *)&inst.suffix,
> +					src + 4, MCOUNT_INSN_SIZE);
> +	if (err)
> +		return err;
> +
> +	ppc_inst_write(p, inst);
> +	return 0;
>  }
> 
>  static ppc_inst
> diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> index d1dff1dc3a11..3e4fbb5c1b1e 100644
> --- a/arch/powerpc/kernel/uprobes.c
> +++ b/arch/powerpc/kernel/uprobes.c
> @@ -111,7 +111,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(ppc_inst_read(auprobe->insn));
> 
>  	user_disable_single_step(current);
>  	return 0;
> diff --git a/arch/powerpc/lib/code-patching.c
> b/arch/powerpc/lib/code-patching.c index fa7f32adf029..3b8277a64b8f 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -24,17 +24,27 @@ static int __patch_instruction(ppc_inst *exec_addr,
> ppc_inst instr, {
>  	int err = 0;
> 
> -	__put_user_asm(instr, patch_addr, err, "stw");
> +	__put_user_asm(ppc_inst_word(instr), patch_addr, err, "stw");
>  	if (err)
>  		return err;
> 
>  	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
>  							    "r" (exec_addr));
> 
> +	if (!ppc_inst_prefixed(instr))
> +		return 0;
> +
> +	__put_user_asm(ppc_inst_suffix(instr), patch_addr + 4, err, "stw");
> +	if (err)
> +		return err;
> +
> +	asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr + 4),
> +							    "r" (exec_addr + 4));
> +
>  	return 0;
>  }
> 
> -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
> +int raw_patch_instruction(void *addr, ppc_inst instr)
>  {
>  	return __patch_instruction(addr, instr, addr);
>  }
> @@ -184,7 +194,7 @@ static int do_patch_instruction(ppc_inst *addr, ppc_inst
> instr)
> 
>  #endif /* CONFIG_STRICT_KERNEL_RWX */
> 
> -int patch_instruction(unsigned int *addr, unsigned int instr)
> +int patch_instruction(void *addr, ppc_inst instr)
>  {
>  	/* Make sure we aren't patching a freed init section */
>  	if (init_mem_is_free && init_section_contains(addr, 4)) {
> @@ -195,7 +205,7 @@ int patch_instruction(unsigned int *addr, unsigned int
> instr) }
>  NOKPROBE_SYMBOL(patch_instruction);
> 
> -int patch_branch(ppc_inst *addr, unsigned long target, int flags)
> +int patch_branch(void *addr, unsigned long target, int flags)
>  {
>  	return patch_instruction(addr, create_branch(addr, target, flags));
>  }
> @@ -264,7 +274,7 @@ ppc_inst create_branch(const ppc_inst *addr,
>  	return instruction;
>  }
> 
> -unsigned int create_cond_branch(const unsigned int *addr,
> +ppc_inst create_cond_branch(const void *addr,
>  				unsigned long target, int flags)
>  {
>  	ppc_inst instruction;
> @@ -344,7 +354,7 @@ static unsigned long branch_bform_target(const ppc_inst
> *instr) return (unsigned long)imm;
>  }
> 
> -unsigned long branch_target(const ppc_inst *instr)
> +unsigned long branch_target(const void *instr)
>  {
>  	if (instr_is_branch_iform(ppc_inst_read(instr)))
>  		return branch_iform_target(instr);
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index bae878a83fa5..ab4c71c43c8c 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1169,10 +1169,12 @@ int analyse_instr(struct instruction_op *op, const
> struct pt_regs *regs, unsigned long int imm;
>  	unsigned long int val, val2;
>  	unsigned int mb, me, sh;
> -	unsigned int word;
> +	unsigned int word, suffix;
>  	long ival;
> 
>  	word = ppc_inst_word(instr);
> +	suffix = ppc_inst_suffix(instr);
> +
>  	op->type = COMPUTE;
> 
>  	opcode = word >> 26;
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index ee084411f2f5..c5536e1a3356 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -110,7 +110,7 @@ struct bpt {
>  #define BP_DABR		4
> 
>  #define NBPTS	256
> -#define BPT_WORDS	2
> +#define BPT_WORDS	4
>  static struct bpt bpts[NBPTS];
>  static struct bpt dabr;
>  static struct bpt *iabr;
> @@ -118,12 +118,13 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
> 
>  #define BP_NUM(bp)	((bp) - bpts + 1)
> 
> -static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS *
> BPT_WORDS]; +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS
> * BPT_WORDS] __aligned(64);
> 
>  /* Prototypes */
>  static int cmds(struct pt_regs *);
>  static int mread(unsigned long, void *, int);
>  static int mwrite(unsigned long, void *, int);
> +static int mread_instr(unsigned long, ppc_inst *);
>  static int handle_fault(struct pt_regs *);
>  static void byterev(unsigned char *, int);
>  static void memex(void);
> @@ -759,8 +760,8 @@ static int xmon_bpt(struct pt_regs *regs)
> 
>  	/* Are we at the trap at bp->instr[1] for some bp? */
>  	bp = in_breakpoint_table(regs->nip, &offset);
> -	if (bp != NULL && offset == 4) {
> -		regs->nip = bp->address + 4;
> +	if (bp != NULL && (offset == 4 || offset == 8)) {
> +		regs->nip = bp->address + offset;
>  		atomic_dec(&bp->ref_count);
>  		return 1;
>  	}
> @@ -862,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long
> nip, unsigned long *offp) if (off >= sizeof(bpt_table))
>  		return NULL;
>  	bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> -	if (bp_off != 0 && bp_off != 4)
> +	if (bp_off != 0 && bp_off != 4 && bp_off != 8)
>  		return NULL;
>  	*offp = bp_off;
>  	return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
> @@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a)
>  		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
>  			bp->address = a;
>  			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> -			patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
>  			return bp;
>  		}
>  	}
> @@ -900,7 +900,7 @@ static void insert_bpts(void)
>  	for (i = 0; i < NBPTS; ++i, ++bp) {
>  		if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
>  			continue;
> -		if (mread(bp->address, &instr, 4) != 4) {
> +		if (!mread_instr(bp->address, &instr)) {
>  			printf("Couldn't read instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
>  			bp->enabled = 0;
> @@ -913,9 +913,10 @@ static void insert_bpts(void)
>  			continue;
>  		}
>  		patch_instruction(bp->instr, instr);
> +		patch_instruction(bp->instr + ppc_inst_len(instr), PPC_INST(bpinstr));
>  		if (bp->enabled & BP_CIABR)
>  			continue;
> -		if (patch_instruction((ppc_inst *)bp->address,
> +		if (patch_instruction((void *)bp->address,
>  							PPC_INST(bpinstr)) != 0) {
>  			printf("Couldn't write instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
> @@ -950,7 +951,7 @@ static void remove_bpts(void)
>  	for (i = 0; i < NBPTS; ++i, ++bp) {
>  		if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
>  			continue;
> -		if (mread(bp->address, &instr, 4) == 4
> +		if (mread_instr(bp->address, &instr)
>  		    && ppc_inst_equal(instr, PPC_INST(bpinstr))
>  		    && patch_instruction(
>  			(ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0)
> @@ -1166,7 +1167,7 @@ static int do_step(struct pt_regs *regs)
>  	force_enable_xmon();
>  	/* check we are in 64-bit kernel mode, translation enabled */
>  	if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
> -		if (mread(regs->nip, &instr, 4) == 4) {
> +		if (mread_instr(regs->nip, &instr)) {
>  			stepped = emulate_step(regs, instr);
>  			if (stepped < 0) {
>  				printf("Couldn't single-step %s instruction\n",
> @@ -1333,7 +1334,7 @@ static long check_bp_loc(unsigned long addr)
>  		printf("Breakpoints may only be placed at kernel addresses\n");
>  		return 0;
>  	}
> -	if (!mread(addr, &instr, sizeof(instr))) {
> +	if (!mread_instr(addr, &instr)) {
>  		printf("Can't read instruction at address %lx\n", addr);
>  		return 0;
>  	}
> @@ -2126,6 +2127,21 @@ mwrite(unsigned long adrs, void *buf, int size)
>  	return n;
>  }
> 
> +static int
> +mread_instr(unsigned long adrs, ppc_inst *instr)
> +{
> +	if (setjmp(bus_error_jmp) == 0) {
> +		catch_memory_errors = 1;
> +		sync();
> +		*instr = ppc_inst_read((void *)adrs);
> +		sync();
> +		/* wait a little while to see if we get a machine check */
> +		__delay(200);
> +	}
> +	catch_memory_errors = 0;
> +	return ppc_inst_len(*instr);
> +}
> +
>  static int fault_type;
>  static int fault_except;
>  static char *fault_chars[] = { "--", "**", "##" };




^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type
  2020-03-30  9:05   ` Alistair Popple
@ 2020-03-30  9:13     ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-03-30  9:13 UTC (permalink / raw)
  To: Alistair Popple
  Cc: Nicholas Piggin, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Mon, Mar 30, 2020 at 8:05 PM Alistair Popple <alistair@popple.id.au> wrote:
>
> <snip>
>
> > @@ -487,12 +487,13 @@ int kprobe_post_handler(struct pt_regs *regs)
> >  {
> >       struct kprobe *cur = kprobe_running();
> >       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> > +     int len = ppc_inst_len(ppc_inst_read(cur->ainsn.insn));
>
> I am no kprobes expert but it seems based on the code here that in some
> circumstances it's ok/expected that cur == NULL, therefore the assignment
> needs to happen after the check below to avoid dereferencing NULL. At least
> this was the problem I was hitting when running some of the kernel selftests.
>
> - Alistair
>
> >       if (!cur || user_mode(regs))
> >               return 0;
Thank you for pointing that out. I'll move the assignment down here.
> >
> >       /* 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) {
> > @@ -501,7 +502,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/optprobes.c
> > b/arch/powerpc/kernel/optprobes.c index 5b53c373373b..af6761859fba 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -158,38 +158,38 @@ void patch_imm32_load_insns(unsigned int val,
> > kprobe_opcode_t *addr)
> >
> >  /*
> >   * Generate instructions to load provided immediate 64-bit value
> > - * to register 'r3' and patch these instructions at 'addr'.
> > + * to register 'reg' and patch these instructions at 'addr'.
> >   */
> > -void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
> > +void patch_imm64_load_insns(unsigned long val, int reg, kprobe_opcode_t
> > *addr) {
> > -     /* lis r3,(op)@highest */
> > -     patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(3) |
> > +     /* lis reg,(op)@highest */
> > +     patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(reg) |
> >                         ((val >> 48) & 0xffff)));
> >       addr++;
> >
> > -     /* ori r3,r3,(op)@higher */
> > -     patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
> > -                       ___PPC_RS(3) | ((val >> 32) & 0xffff)));
> > +     /* ori reg,reg,(op)@higher */
> > +     patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
> > +                       ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
> >       addr++;
> >
> > -     /* rldicr r3,r3,32,31 */
> > -     patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(3) |
> > -                       ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)));
> > +     /* rldicr reg,reg,32,31 */
> > +     patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(reg) |
> > +                       ___PPC_RS(reg) | __PPC_SH64(32) | __PPC_ME64(31)));
> >       addr++;
> >
> > -     /* oris r3,r3,(op)@h */
> > -     patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(3) |
> > -                       ___PPC_RS(3) | ((val >> 16) & 0xffff)));
> > +     /* oris reg,reg,(op)@h */
> > +     patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(reg) |
> > +                       ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
> >       addr++;
> >
> > -     /* ori r3,r3,(op)@l */
> > -     patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) |
> > -                       ___PPC_RS(3) | (val & 0xffff)));
> > +     /* ori reg,reg,(op)@l */
> > +     patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) |
> > +                       ___PPC_RS(reg) | (val & 0xffff)));
> >  }
> >
> >  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct
> > kprobe *p) {
> > -     ppc_inst branch_op_callback, branch_emulate_step;
> > +     ppc_inst branch_op_callback, branch_emulate_step, temp;
> >       kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
> >       long b_offset;
> >       unsigned long nip, size;
> > @@ -239,7 +239,7 @@ int arch_prepare_optimized_kprobe(struct
> > optimized_kprobe *op, struct kprobe *p) * Fixup the template with
> > instructions to:
> >        * 1. load the address of the actual probepoint
> >        */
> > -     patch_imm64_load_insns((unsigned long)op, buff + TMPL_OP_IDX);
> > +     patch_imm64_load_insns((unsigned long)op, 3, buff + TMPL_OP_IDX);
> >
> >       /*
> >        * 2. branch to optimized_callback() and emulate_step()
> > @@ -268,7 +268,11 @@ int arch_prepare_optimized_kprobe(struct
> > optimized_kprobe *op, struct kprobe *p) /*
> >        * 3. load instruction to be emulated into relevant register, and
> >        */
> > -     patch_imm32_load_insns(*(unsigned int *)p->ainsn.insn, buff +
> > TMPL_INSN_IDX); +     temp = ppc_inst_read(p->ainsn.insn);
> > +     patch_imm64_load_insns(ppc_inst_word(temp) |
> > +                            ((u64)ppc_inst_suffix(temp) << 32),
> > +                            4,
> > +                            buff + TMPL_INSN_IDX);
> >
> >       /*
> >        * 4. branch back from trampoline
> > diff --git a/arch/powerpc/kernel/optprobes_head.S
> > b/arch/powerpc/kernel/optprobes_head.S index cf383520843f..ff8ba4d3824d
> > 100644
> > --- a/arch/powerpc/kernel/optprobes_head.S
> > +++ b/arch/powerpc/kernel/optprobes_head.S
> > @@ -94,6 +94,9 @@ optprobe_template_insn:
> >       /* 2, Pass instruction to be emulated in r4 */
> >       nop
> >       nop
> > +     nop
> > +     nop
> > +     nop
> >
> >       .global optprobe_template_call_emulate
> >  optprobe_template_call_emulate:
> > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > b/arch/powerpc/kernel/trace/ftrace.c index ad451205f268..3b8655f57b4a
> > 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -42,9 +42,24 @@
> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> >
> >  static long
> > -read_inst(ppc_inst *inst, const void *src)
> > +read_inst(ppc_inst *p, const void *src)
> >  {
> > -     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> > +     ppc_inst inst;
> > +     long err;
> > +
> > +     err = probe_kernel_read((void *)&inst.prefix,
> > +                             src, MCOUNT_INSN_SIZE);
> > +     if (err)
> > +             return err;
> > +
> > +     if (ppc_inst_prefixed(inst))
> > +             err = probe_kernel_read((void *)&inst.suffix,
> > +                                     src + 4, MCOUNT_INSN_SIZE);
> > +     if (err)
> > +             return err;
> > +
> > +     ppc_inst_write(p, inst);
> > +     return 0;
> >  }
> >
> >  static ppc_inst
> > diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> > index d1dff1dc3a11..3e4fbb5c1b1e 100644
> > --- a/arch/powerpc/kernel/uprobes.c
> > +++ b/arch/powerpc/kernel/uprobes.c
> > @@ -111,7 +111,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(ppc_inst_read(auprobe->insn));
> >
> >       user_disable_single_step(current);
> >       return 0;
> > diff --git a/arch/powerpc/lib/code-patching.c
> > b/arch/powerpc/lib/code-patching.c index fa7f32adf029..3b8277a64b8f 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -24,17 +24,27 @@ static int __patch_instruction(ppc_inst *exec_addr,
> > ppc_inst instr, {
> >       int err = 0;
> >
> > -     __put_user_asm(instr, patch_addr, err, "stw");
> > +     __put_user_asm(ppc_inst_word(instr), patch_addr, err, "stw");
> >       if (err)
> >               return err;
> >
> >       asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
> >                                                           "r" (exec_addr));
> >
> > +     if (!ppc_inst_prefixed(instr))
> > +             return 0;
> > +
> > +     __put_user_asm(ppc_inst_suffix(instr), patch_addr + 4, err, "stw");
> > +     if (err)
> > +             return err;
> > +
> > +     asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr + 4),
> > +                                                         "r" (exec_addr + 4));
> > +
> >       return 0;
> >  }
> >
> > -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
> > +int raw_patch_instruction(void *addr, ppc_inst instr)
> >  {
> >       return __patch_instruction(addr, instr, addr);
> >  }
> > @@ -184,7 +194,7 @@ static int do_patch_instruction(ppc_inst *addr, ppc_inst
> > instr)
> >
> >  #endif /* CONFIG_STRICT_KERNEL_RWX */
> >
> > -int patch_instruction(unsigned int *addr, unsigned int instr)
> > +int patch_instruction(void *addr, ppc_inst instr)
> >  {
> >       /* Make sure we aren't patching a freed init section */
> >       if (init_mem_is_free && init_section_contains(addr, 4)) {
> > @@ -195,7 +205,7 @@ int patch_instruction(unsigned int *addr, unsigned int
> > instr) }
> >  NOKPROBE_SYMBOL(patch_instruction);
> >
> > -int patch_branch(ppc_inst *addr, unsigned long target, int flags)
> > +int patch_branch(void *addr, unsigned long target, int flags)
> >  {
> >       return patch_instruction(addr, create_branch(addr, target, flags));
> >  }
> > @@ -264,7 +274,7 @@ ppc_inst create_branch(const ppc_inst *addr,
> >       return instruction;
> >  }
> >
> > -unsigned int create_cond_branch(const unsigned int *addr,
> > +ppc_inst create_cond_branch(const void *addr,
> >                               unsigned long target, int flags)
> >  {
> >       ppc_inst instruction;
> > @@ -344,7 +354,7 @@ static unsigned long branch_bform_target(const ppc_inst
> > *instr) return (unsigned long)imm;
> >  }
> >
> > -unsigned long branch_target(const ppc_inst *instr)
> > +unsigned long branch_target(const void *instr)
> >  {
> >       if (instr_is_branch_iform(ppc_inst_read(instr)))
> >               return branch_iform_target(instr);
> > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > index bae878a83fa5..ab4c71c43c8c 100644
> > --- a/arch/powerpc/lib/sstep.c
> > +++ b/arch/powerpc/lib/sstep.c
> > @@ -1169,10 +1169,12 @@ int analyse_instr(struct instruction_op *op, const
> > struct pt_regs *regs, unsigned long int imm;
> >       unsigned long int val, val2;
> >       unsigned int mb, me, sh;
> > -     unsigned int word;
> > +     unsigned int word, suffix;
> >       long ival;
> >
> >       word = ppc_inst_word(instr);
> > +     suffix = ppc_inst_suffix(instr);
> > +
> >       op->type = COMPUTE;
> >
> >       opcode = word >> 26;
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index ee084411f2f5..c5536e1a3356 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -110,7 +110,7 @@ struct bpt {
> >  #define BP_DABR              4
> >
> >  #define NBPTS        256
> > -#define BPT_WORDS    2
> > +#define BPT_WORDS    4
> >  static struct bpt bpts[NBPTS];
> >  static struct bpt dabr;
> >  static struct bpt *iabr;
> > @@ -118,12 +118,13 @@ static unsigned bpinstr = 0x7fe00008;   /* trap */
> >
> >  #define BP_NUM(bp)   ((bp) - bpts + 1)
> >
> > -static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS *
> > BPT_WORDS]; +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS
> > * BPT_WORDS] __aligned(64);
> >
> >  /* Prototypes */
> >  static int cmds(struct pt_regs *);
> >  static int mread(unsigned long, void *, int);
> >  static int mwrite(unsigned long, void *, int);
> > +static int mread_instr(unsigned long, ppc_inst *);
> >  static int handle_fault(struct pt_regs *);
> >  static void byterev(unsigned char *, int);
> >  static void memex(void);
> > @@ -759,8 +760,8 @@ static int xmon_bpt(struct pt_regs *regs)
> >
> >       /* Are we at the trap at bp->instr[1] for some bp? */
> >       bp = in_breakpoint_table(regs->nip, &offset);
> > -     if (bp != NULL && offset == 4) {
> > -             regs->nip = bp->address + 4;
> > +     if (bp != NULL && (offset == 4 || offset == 8)) {
> > +             regs->nip = bp->address + offset;
> >               atomic_dec(&bp->ref_count);
> >               return 1;
> >       }
> > @@ -862,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long
> > nip, unsigned long *offp) if (off >= sizeof(bpt_table))
> >               return NULL;
> >       bp_off = off % (sizeof(unsigned int) * BPT_WORDS);
> > -     if (bp_off != 0 && bp_off != 4)
> > +     if (bp_off != 0 && bp_off != 4 && bp_off != 8)
> >               return NULL;
> >       *offp = bp_off;
> >       return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS));
> > @@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a)
> >               if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
> >                       bp->address = a;
> >                       bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> > -                     patch_instruction(bp->instr + 1, PPC_INST(bpinstr));
> >                       return bp;
> >               }
> >       }
> > @@ -900,7 +900,7 @@ static void insert_bpts(void)
> >       for (i = 0; i < NBPTS; ++i, ++bp) {
> >               if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
> >                       continue;
> > -             if (mread(bp->address, &instr, 4) != 4) {
> > +             if (!mread_instr(bp->address, &instr)) {
> >                       printf("Couldn't read instruction at %lx, "
> >                              "disabling breakpoint there\n", bp->address);
> >                       bp->enabled = 0;
> > @@ -913,9 +913,10 @@ static void insert_bpts(void)
> >                       continue;
> >               }
> >               patch_instruction(bp->instr, instr);
> > +             patch_instruction(bp->instr + ppc_inst_len(instr), PPC_INST(bpinstr));
> >               if (bp->enabled & BP_CIABR)
> >                       continue;
> > -             if (patch_instruction((ppc_inst *)bp->address,
> > +             if (patch_instruction((void *)bp->address,
> >                                                       PPC_INST(bpinstr)) != 0) {
> >                       printf("Couldn't write instruction at %lx, "
> >                              "disabling breakpoint there\n", bp->address);
> > @@ -950,7 +951,7 @@ static void remove_bpts(void)
> >       for (i = 0; i < NBPTS; ++i, ++bp) {
> >               if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
> >                       continue;
> > -             if (mread(bp->address, &instr, 4) == 4
> > +             if (mread_instr(bp->address, &instr)
> >                   && ppc_inst_equal(instr, PPC_INST(bpinstr))
> >                   && patch_instruction(
> >                       (ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0)
> > @@ -1166,7 +1167,7 @@ static int do_step(struct pt_regs *regs)
> >       force_enable_xmon();
> >       /* check we are in 64-bit kernel mode, translation enabled */
> >       if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
> > -             if (mread(regs->nip, &instr, 4) == 4) {
> > +             if (mread_instr(regs->nip, &instr)) {
> >                       stepped = emulate_step(regs, instr);
> >                       if (stepped < 0) {
> >                               printf("Couldn't single-step %s instruction\n",
> > @@ -1333,7 +1334,7 @@ static long check_bp_loc(unsigned long addr)
> >               printf("Breakpoints may only be placed at kernel addresses\n");
> >               return 0;
> >       }
> > -     if (!mread(addr, &instr, sizeof(instr))) {
> > +     if (!mread_instr(addr, &instr)) {
> >               printf("Can't read instruction at address %lx\n", addr);
> >               return 0;
> >       }
> > @@ -2126,6 +2127,21 @@ mwrite(unsigned long adrs, void *buf, int size)
> >       return n;
> >  }
> >
> > +static int
> > +mread_instr(unsigned long adrs, ppc_inst *instr)
> > +{
> > +     if (setjmp(bus_error_jmp) == 0) {
> > +             catch_memory_errors = 1;
> > +             sync();
> > +             *instr = ppc_inst_read((void *)adrs);
> > +             sync();
> > +             /* wait a little while to see if we get a machine check */
> > +             __delay(200);
> > +     }
> > +     catch_memory_errors = 0;
> > +     return ppc_inst_len(*instr);
> > +}
> > +
> >  static int fault_type;
> >  static int fault_except;
> >  static char *fault_chars[] = { "--", "**", "##" };
>
>
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-03-20  5:17 ` [PATCH v4 03/16] powerpc: Use a datatype for instructions Jordan Niethe
  2020-03-23  6:07   ` Balamuruhan S
  2020-03-23  6:23   ` Nicholas Piggin
@ 2020-04-01 10:32   ` Balamuruhan S
  2020-04-01 23:52     ` Jordan Niethe
  2 siblings, 1 reply; 65+ messages in thread
From: Balamuruhan S @ 2020-04-01 10:32 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> Currently unsigned ints are used to represent instructions on powerpc.
> This has worked well as instructions have always been 4 byte words.
> However, a future ISA version will introduce some changes to
> instructions that mean this scheme will no longer work as well. This
> change is Prefixed Instructions. A prefixed instruction is made up of a
> word prefix followed by a word suffix to make an 8 byte double word
> instruction. No matter the endianess of the system the prefix always
> comes first. Prefixed instructions are only planned for powerpc64.
> 
> Introduce a ppc_inst type to represent both prefixed and word
> instructions on powerpc64 while keeping it possible to exclusively have
> word instructions on powerpc32, A latter patch will expand the type to
> include prefixed instructions but for now just typedef it to a u32.
> 
> Later patches will introduce helper functions and macros for
> manipulating the instructions so that powerpc64 and powerpc32 might
> maintain separate type definitions.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>  arch/powerpc/include/asm/code-patching.h | 31 +++++------
>  arch/powerpc/include/asm/inst.h          | 53 +++++++++++++++++++
>  arch/powerpc/include/asm/sstep.h         |  5 +-
>  arch/powerpc/kernel/align.c              |  2 +-
>  arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
>  arch/powerpc/kernel/kprobes.c            |  2 +-
>  arch/powerpc/kernel/mce_power.c          |  5 +-
>  arch/powerpc/kernel/optprobes.c          | 10 ++--
>  arch/powerpc/kernel/trace/ftrace.c       | 66 ++++++++++++------------
>  arch/powerpc/kvm/emulate_loadstore.c     |  1 +
>  arch/powerpc/lib/code-patching.c         | 54 +++++++++----------
>  arch/powerpc/lib/sstep.c                 |  4 +-
>  arch/powerpc/lib/test_emulate_step.c     |  9 ++--
>  arch/powerpc/xmon/xmon.c                 | 12 ++---
>  14 files changed, 160 insertions(+), 97 deletions(-)
>  create mode 100644 arch/powerpc/include/asm/inst.h
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h
> b/arch/powerpc/include/asm/code-patching.h
> index 898b54262881..cb5106f92d67 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -11,6 +11,7 @@
>  #include <linux/string.h>
>  #include <linux/kallsyms.h>
>  #include <asm/asm-compat.h>
> +#include <asm/inst.h>
>  
>  /* Flags for create_branch:
>   * "b"   == create_branch(addr, target, 0);
> @@ -22,27 +23,27 @@
>  #define BRANCH_ABSOLUTE	0x2
>  
>  bool is_offset_in_branch_range(long offset);
> -unsigned int create_branch(const unsigned int *addr,
> +ppc_inst create_branch(const ppc_inst *addr,
>  			   unsigned long target, int flags);
> -unsigned int create_cond_branch(const unsigned int *addr,
> +unsigned int create_cond_branch(const ppc_inst *addr,
>  				unsigned long target, int flags);
> -int patch_branch(unsigned int *addr, unsigned long target, int flags);
> -int patch_instruction(unsigned int *addr, unsigned int instr);
> -int raw_patch_instruction(unsigned int *addr, unsigned int instr);
> +int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> +int patch_instruction(ppc_inst *addr, ppc_inst instr);

we need to handle this change for its user in epapr_paravirt.c,

arch/powerpc/kernel/epapr_paravirt.c: In function 'early_init_dt_scan_epapr':
arch/powerpc/kernel/epapr_paravirt.c:40:48: error: incompatible type for
argument 2 of 'patch_instruction'
   40 |   patch_instruction(epapr_hypercall_start + i, inst);
      |                                                ^~~~
      |                                                |
      |                                                u32 {aka unsigned int}
In file included from arch/powerpc/kernel/epapr_paravirt.c:12:
./arch/powerpc/include/asm/code-patching.h:31:44: note: expected 'ppc_inst'
{aka 'struct ppc_inst'} but argument is of type 'u32' {aka 'unsigned int'}
   31 | int patch_instruction(void *addr, ppc_inst instr);
      |                                   ~~~~~~~~~^~~~~
make[2]: *** [scripts/Makefile.build:268: arch/powerpc/kernel/epapr_paravirt.o]
Error 1
make[1]: *** [scripts/Makefile.build:505: arch/powerpc/kernel] Error 2
make: *** [Makefile:1683: arch/powerpc] Error 2


-- Bala

> +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
>  
>  static inline unsigned long patch_site_addr(s32 *site)
>  {
>  	return (unsigned long)site + *site;
>  }
>  
> -static inline int patch_instruction_site(s32 *site, unsigned int instr)
> +static inline int patch_instruction_site(s32 *site, ppc_inst instr)
>  {
> -	return patch_instruction((unsigned int *)patch_site_addr(site), instr);
> +	return patch_instruction((ppc_inst *)patch_site_addr(site), instr);
>  }
>  
>  static inline int patch_branch_site(s32 *site, unsigned long target, int
> flags)
>  {
> -	return patch_branch((unsigned int *)patch_site_addr(site), target,
> flags);
> +	return patch_branch((ppc_inst *)patch_site_addr(site), target, flags);
>  }
>  
>  static inline int modify_instruction(unsigned int *addr, unsigned int clr,
> @@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site,
> unsigned int clr, unsigned
>  	return modify_instruction((unsigned int *)patch_site_addr(site), clr,
> set);
>  }
>  
> -int instr_is_relative_branch(unsigned int instr);
> -int instr_is_relative_link_branch(unsigned int instr);
> -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
> -unsigned long branch_target(const unsigned int *instr);
> -unsigned int translate_branch(const unsigned int *dest,
> -			      const unsigned int *src);
> -extern bool is_conditional_branch(unsigned int instr);
> +int instr_is_relative_branch(ppc_inst instr);
> +int instr_is_relative_link_branch(ppc_inst instr);
> +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> +unsigned long branch_target(const ppc_inst *instr);
> +ppc_inst translate_branch(const ppc_inst *dest,
> +			      const ppc_inst *src);
> +extern bool is_conditional_branch(ppc_inst instr);
>  #ifdef CONFIG_PPC_BOOK3E_64
>  void __patch_exception(int exc, unsigned long addr);
>  #define patch_exception(exc, name) do { \
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> new file mode 100644
> index 000000000000..7c8596ee411e
> --- /dev/null
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -0,0 +1,53 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#ifndef _ASM_INST_H
> +#define _ASM_INST_H
> +
> +/*
> + * Instruction data type for POWER
> + */
> +
> +typedef u32 ppc_inst;
> +
> +#define PPC_INST(x) (x)
> +
> +static inline int ppc_inst_len(ppc_inst x)
> +{
> +	return sizeof(ppc_inst);
> +}
> +
> +static inline int ppc_inst_opcode(ppc_inst x)
> +{
> +	return x >> 26;
> +}
> +
> +static inline u32 ppc_inst_word(ppc_inst x)
> +{
> +	return x;
> +}
> +
> +static inline ppc_inst ppc_inst_read(const ppc_inst *ptr)
> +{
> +	return *(ppc_inst *)ptr;
> +}
> +
> +static inline void ppc_inst_write(void *ptr, ppc_inst x)
> +{
> +	*(ppc_inst *)ptr = x;
> +}
> +
> +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
> +{
> +	return x == y;
> +}
> +
> +static inline bool ppc_inst_null(ppc_inst x)
> +{
> +	return x == 0;
> +}
> +
> +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
> +{
> +	return ppc_inst_word(x) & mask;
> +}
> +
> +#endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/include/asm/sstep.h
> b/arch/powerpc/include/asm/sstep.h
> index 769f055509c9..9353916fcba7 100644
> --- a/arch/powerpc/include/asm/sstep.h
> +++ b/arch/powerpc/include/asm/sstep.h
> @@ -2,6 +2,7 @@
>  /*
>   * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
>   */
> +#include <asm/inst.h>
>  
>  struct pt_regs;
>  
> @@ -132,7 +133,7 @@ union vsx_reg {
>   * otherwise.
>   */
>  extern int analyse_instr(struct instruction_op *op, const struct pt_regs
> *regs,
> -			 unsigned int instr);
> +			 ppc_inst instr);
>  
>  /*
>   * Emulate an instruction that can be executed just by updating
> @@ -149,7 +150,7 @@ 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, ppc_inst instr);
>  
>  /*
>   * 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..34594aaa44de 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -293,7 +293,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int
> reg,
>  
>  int fix_alignment(struct pt_regs *regs)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  	struct instruction_op op;
>  	int r, type;
>  
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> b/arch/powerpc/kernel/hw_breakpoint.c
> index 2462cd7c565c..06b97353d231 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -24,6 +24,7 @@
>  #include <asm/debug.h>
>  #include <asm/debugfs.h>
>  #include <asm/hvcall.h>
> +#include <asm/inst.h>
>  #include <linux/uaccess.h>
>  
>  /*
> @@ -243,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size, struct
> arch_hw_breakpoint *info)
>  static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
>  			     struct arch_hw_breakpoint *info)
>  {
> -	unsigned int instr = 0;
> +	ppc_inst instr = 0;
>  	int ret, type, size;
>  	struct instruction_op op;
>  	unsigned long addr = info->address;
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 337516df17d4..e7205adc9820 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
>  static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
>  {
>  	int ret;
> -	unsigned int insn = *p->ainsn.insn;
> +	ppc_inst insn = *p->ainsn.insn;
>  
>  	/* regs->nip is also adjusted if emulate_step returns 1 */
>  	ret = emulate_step(regs, insn);
> diff --git a/arch/powerpc/kernel/mce_power.c
> b/arch/powerpc/kernel/mce_power.c
> index 1cbf7f1a4e3d..e65616bb3a3e 100644
> --- a/arch/powerpc/kernel/mce_power.c
> +++ b/arch/powerpc/kernel/mce_power.c
> @@ -20,6 +20,7 @@
>  #include <asm/sstep.h>
>  #include <asm/exception-64s.h>
>  #include <asm/extable.h>
> +#include <asm/inst.h>
>  
>  /*
>   * Convert an address related to an mm to a PFN. NOTE: we are in real
> @@ -365,7 +366,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> *regs, uint64_t *addr,
>  	 * in real-mode is tricky and can lead to recursive
>  	 * faults
>  	 */
> -	int instr;
> +	ppc_inst instr;
>  	unsigned long pfn, instr_addr;
>  	struct instruction_op op;
>  	struct pt_regs tmp = *regs;
> @@ -373,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> *regs, uint64_t *addr,
>  	pfn = addr_to_pfn(regs, regs->nip);
>  	if (pfn != ULONG_MAX) {
>  		instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
> -		instr = *(unsigned int *)(instr_addr);
> +		instr = *(ppc_inst *)(instr_addr);
>  		if (!analyse_instr(&op, &tmp, instr)) {
>  			pfn = addr_to_pfn(regs, op.ea);
>  			*addr = op.ea;
> diff --git a/arch/powerpc/kernel/optprobes.c
> b/arch/powerpc/kernel/optprobes.c
> index 024f7aad1952..f5e8cce438a3 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -189,8 +189,8 @@ void patch_imm64_load_insns(unsigned long val,
> kprobe_opcode_t *addr)
>  
>  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe
> *p)
>  {
> -	kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
> -	kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
> +	ppc_inst branch_op_callback, branch_emulate_step;
> +	kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
>  	long b_offset;
>  	unsigned long nip, size;
>  	int rc, i;
> @@ -251,11 +251,11 @@ int arch_prepare_optimized_kprobe(struct
> optimized_kprobe *op, struct kprobe *p)
>  		goto error;
>  	}
>  
> -	branch_op_callback = create_branch((unsigned int *)buff +
> TMPL_CALL_HDLR_IDX,
> +	branch_op_callback = create_branch((ppc_inst *)buff +
> TMPL_CALL_HDLR_IDX,
>  				(unsigned long)op_callback_addr,
>  				BRANCH_SET_LINK);
>  
> -	branch_emulate_step = create_branch((unsigned int *)buff +
> TMPL_EMULATE_IDX,
> +	branch_emulate_step = create_branch((ppc_inst *)buff +
> TMPL_EMULATE_IDX,
>  				(unsigned long)emulate_step_addr,
>  				BRANCH_SET_LINK);
>  
> @@ -316,7 +316,7 @@ void arch_optimize_kprobes(struct list_head *oplist)
>  		memcpy(op->optinsn.copied_insn, op->kp.addr,
>  					       RELATIVEJUMP_SIZE);
>  		patch_instruction(op->kp.addr,
> -			create_branch((unsigned int *)op->kp.addr,
> +			create_branch((ppc_inst *)op->kp.addr,
>  				      (unsigned long)op->optinsn.insn, 0));
>  		list_del_init(&op->list);
>  	}
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c
> index 7ea0ca044b65..5787ccffb4df 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -27,6 +27,7 @@
>  #include <asm/code-patching.h>
>  #include <asm/ftrace.h>
>  #include <asm/syscall.h>
> +#include <asm/inst.h>
>  
>  
>  #ifdef CONFIG_DYNAMIC_FTRACE
> @@ -40,23 +41,23 @@
>  #define	NUM_FTRACE_TRAMPS	8
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
>  
> -static unsigned int
> +static ppc_inst
>  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  
>  	addr = ppc_function_entry((void *)addr);
>  
>  	/* if (link) set op to 'bl' else 'b' */
> -	op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> +	op = create_branch((ppc_inst *)ip, addr, link ? 1 : 0);
>  
>  	return op;
>  }
>  
>  static int
> -ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
> +ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
>  {
> -	unsigned int replaced;
> +	ppc_inst replaced;
>  
>  	/*
>  	 * Note:
> @@ -78,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> unsigned int new)
>  	}
>  
>  	/* replace the text with the new text */
> -	if (patch_instruction((unsigned int *)ip, new))
> +	if (patch_instruction((ppc_inst *)ip, new))
>  		return -EPERM;
>  
>  	return 0;
> @@ -87,25 +88,25 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> unsigned int new)
>  /*
>   * Helper functions that are the same for both PPC64 and PPC32.
>   */
> -static int test_24bit_addr(unsigned long ip, unsigned long addr)
> +static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr)
>  {
>  	addr = ppc_function_entry((void *)addr);
>  
>  	/* use the create_branch to verify that this offset can be branched */
> -	return create_branch((unsigned int *)ip, addr, 0);
> +	return create_branch((ppc_inst *)ip, addr, 0);
>  }
>  
> -static int is_bl_op(unsigned int op)
> +static int is_bl_op(ppc_inst op)
>  {
>  	return (op & 0xfc000003) == 0x48000001;
>  }
>  
> -static int is_b_op(unsigned int op)
> +static int is_b_op(ppc_inst op)
>  {
>  	return (op & 0xfc000003) == 0x48000000;
>  }
>  
> -static unsigned long find_bl_target(unsigned long ip, unsigned int op)
> +static unsigned long find_bl_target(unsigned long ip, ppc_inst op)
>  {
>  	int offset;
>  
> @@ -125,7 +126,7 @@ __ftrace_make_nop(struct module *mod,
>  {
>  	unsigned long entry, ptr, tramp;
>  	unsigned long ip = rec->ip;
> -	unsigned int op, pop;
> +	ppc_inst op, pop;
>  
>  	/* read where this goes */
>  	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> @@ -204,7 +205,7 @@ __ftrace_make_nop(struct module *mod,
>  	}
>  #endif /* CONFIG_MPROFILE_KERNEL */
>  
> -	if (patch_instruction((unsigned int *)ip, pop)) {
> +	if (patch_instruction((ppc_inst *)ip, pop)) {
>  		pr_err("Patching NOP failed.\n");
>  		return -EPERM;
>  	}
> @@ -217,7 +218,7 @@ static int
>  __ftrace_make_nop(struct module *mod,
>  		  struct dyn_ftrace *rec, unsigned long addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	unsigned int jmp[4];
>  	unsigned long ip = rec->ip;
>  	unsigned long tramp;
> @@ -276,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
>  
>  	op = PPC_INST_NOP;
>  
> -	if (patch_instruction((unsigned int *)ip, op))
> +	if (patch_instruction((ppc_inst *)ip, op))
>  		return -EPERM;
>  
>  	return 0;
> @@ -322,7 +323,8 @@ static int add_ftrace_tramp(unsigned long tramp)
>   */
>  static int setup_mcount_compiler_tramp(unsigned long tramp)
>  {
> -	int i, op;
> +	int i;
> +	ppc_inst op;
>  	unsigned long ptr;
>  	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
>  
> @@ -388,7 +390,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> tramp)
>  static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long
> addr)
>  {
>  	unsigned long tramp, ip = rec->ip;
> -	unsigned int op;
> +	ppc_inst op;
>  
>  	/* Read where this goes */
>  	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> @@ -416,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  		}
>  	}
>  
> -	if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) {
> +	if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) {
>  		pr_err("Patching NOP failed.\n");
>  		return -EPERM;
>  	}
> @@ -428,7 +430,7 @@ int ftrace_make_nop(struct module *mod,
>  		    struct dyn_ftrace *rec, unsigned long addr)
>  {
>  	unsigned long ip = rec->ip;
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -481,7 +483,7 @@ int ftrace_make_nop(struct module *mod,
>   */
>  #ifndef CONFIG_MPROFILE_KERNEL
>  static int
> -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
> +expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
>  {
>  	/*
>  	 * We expect to see:
> @@ -510,7 +512,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> unsigned int op1)
>  static int
>  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
> -	unsigned int op[2];
> +	ppc_inst op[2];
>  	void *ip = (void *)rec->ip;
>  	unsigned long entry, ptr, tramp;
>  	struct module *mod = rec->arch.mod;
> @@ -574,7 +576,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  static int
>  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	unsigned long ip = rec->ip;
>  
>  	/* read where this goes */
> @@ -594,7 +596,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  	}
>  
>  	/* create the branch to the trampoline */
> -	op = create_branch((unsigned int *)ip,
> +	op = create_branch((ppc_inst *)ip,
>  			   rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
>  	if (!op) {
>  		pr_err("REL24 out of range!\n");
> @@ -613,7 +615,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  
>  static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long
> addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	void *ip = (void *)rec->ip;
>  	unsigned long tramp, entry, ptr;
>  
> @@ -661,7 +663,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
>  	unsigned long ip = rec->ip;
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -700,7 +702,7 @@ static int
>  __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
>  					unsigned long addr)
>  {
> -	unsigned int op;
> +	ppc_inst op;
>  	unsigned long ip = rec->ip;
>  	unsigned long entry, ptr, tramp;
>  	struct module *mod = rec->arch.mod;
> @@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  	/* The new target may be within range */
>  	if (test_24bit_addr(ip, addr)) {
>  		/* within range */
> -		if (patch_branch((unsigned int *)ip, addr, BRANCH_SET_LINK)) {
> +		if (patch_branch((ppc_inst *)ip, addr, BRANCH_SET_LINK)) {
>  			pr_err("REL24 out of range!\n");
>  			return -EINVAL;
>  		}
> @@ -776,7 +778,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  	}
>  
>  	/* Ensure branch is within 24 bits */
> -	if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> +	if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
>  		pr_err("Branch out of range\n");
>  		return -EINVAL;
>  	}
> @@ -794,7 +796,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  			unsigned long addr)
>  {
>  	unsigned long ip = rec->ip;
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -834,7 +836,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  int ftrace_update_ftrace_func(ftrace_func_t func)
>  {
>  	unsigned long ip = (unsigned long)(&ftrace_call);
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  	int ret;
>  
>  	old = *(unsigned int *)&ftrace_call;
> @@ -919,7 +921,7 @@ int ftrace_enable_ftrace_graph_caller(void)
>  	unsigned long ip = (unsigned long)(&ftrace_graph_call);
>  	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
>  	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	old = ftrace_call_replace(ip, stub, 0);
>  	new = ftrace_call_replace(ip, addr, 0);
> @@ -932,7 +934,7 @@ int ftrace_disable_ftrace_graph_caller(void)
>  	unsigned long ip = (unsigned long)(&ftrace_graph_call);
>  	unsigned long addr = (unsigned long)(&ftrace_graph_caller);
>  	unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> -	unsigned int old, new;
> +	ppc_inst old, new;
>  
>  	old = ftrace_call_replace(ip, addr, 0);
>  	new = ftrace_call_replace(ip, stub, 0);
> diff --git a/arch/powerpc/kvm/emulate_loadstore.c
> b/arch/powerpc/kvm/emulate_loadstore.c
> index 1139bc56e004..1c9bcbfeb924 100644
> --- a/arch/powerpc/kvm/emulate_loadstore.c
> +++ b/arch/powerpc/kvm/emulate_loadstore.c
> @@ -21,6 +21,7 @@
>  #include <asm/disassemble.h>
>  #include <asm/ppc-opcode.h>
>  #include <asm/sstep.h>
> +#include <asm/inst.h>
>  #include "timing.h"
>  #include "trace.h"
>  
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index 3345f039a876..8492b9e2b8db 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -17,9 +17,10 @@
>  #include <asm/page.h>
>  #include <asm/code-patching.h>
>  #include <asm/setup.h>
> +#include <asm/inst.h>
>  
> -static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
> -			       unsigned int *patch_addr)
> +static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
> +			       ppc_inst *patch_addr)
>  {
>  	int err = 0;
>  
> @@ -33,7 +34,7 @@ static int __patch_instruction(unsigned int *exec_addr,
> unsigned int instr,
>  	return 0;
>  }
>  
> -int raw_patch_instruction(unsigned int *addr, unsigned int instr)
> +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
>  {
>  	return __patch_instruction(addr, instr, addr);
>  }
> @@ -136,10 +137,10 @@ static inline int unmap_patch_area(unsigned long addr)
>  	return 0;
>  }
>  
> -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
>  {
>  	int err;
> -	unsigned int *patch_addr = NULL;
> +	ppc_inst *patch_addr = NULL;
>  	unsigned long flags;
>  	unsigned long text_poke_addr;
>  	unsigned long kaddr = (unsigned long)addr;
> @@ -176,7 +177,7 @@ static int do_patch_instruction(unsigned int *addr,
> unsigned int instr)
>  }
>  #else /* !CONFIG_STRICT_KERNEL_RWX */
>  
> -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
>  {
>  	return raw_patch_instruction(addr, instr);
>  }
> @@ -194,7 +195,7 @@ int patch_instruction(unsigned int *addr, unsigned int
> instr)
>  }
>  NOKPROBE_SYMBOL(patch_instruction);
>  
> -int patch_branch(unsigned int *addr, unsigned long target, int flags)
> +int patch_branch(ppc_inst *addr, unsigned long target, int flags)
>  {
>  	return patch_instruction(addr, create_branch(addr, target, flags));
>  }
> @@ -225,7 +226,7 @@ bool is_offset_in_branch_range(long offset)
>   * Helper to check if a given instruction is a conditional branch
>   * Derived from the conditional checks in analyse_instr()
>   */
> -bool is_conditional_branch(unsigned int instr)
> +bool is_conditional_branch(ppc_inst instr)
>  {
>  	unsigned int opcode = instr >> 26;
>  
> @@ -243,10 +244,10 @@ bool is_conditional_branch(unsigned int instr)
>  }
>  NOKPROBE_SYMBOL(is_conditional_branch);
>  
> -unsigned int create_branch(const unsigned int *addr,
> +ppc_inst create_branch(const ppc_inst *addr,
>  			   unsigned long target, int flags)
>  {
> -	unsigned int instruction;
> +	ppc_inst instruction;
>  	long offset;
>  
>  	offset = target;
> @@ -266,7 +267,7 @@ unsigned int create_branch(const unsigned int *addr,
>  unsigned int create_cond_branch(const unsigned int *addr,
>  				unsigned long target, int flags)
>  {
> -	unsigned int instruction;
> +	ppc_inst instruction;
>  	long offset;
>  
>  	offset = target;
> @@ -283,22 +284,22 @@ unsigned int create_cond_branch(const unsigned int
> *addr,
>  	return instruction;
>  }
>  
> -static unsigned int branch_opcode(unsigned int instr)
> +static unsigned int branch_opcode(ppc_inst instr)
>  {
>  	return (instr >> 26) & 0x3F;
>  }
>  
> -static int instr_is_branch_iform(unsigned int instr)
> +static int instr_is_branch_iform(ppc_inst instr)
>  {
>  	return branch_opcode(instr) == 18;
>  }
>  
> -static int instr_is_branch_bform(unsigned int instr)
> +static int instr_is_branch_bform(ppc_inst instr)
>  {
>  	return branch_opcode(instr) == 16;
>  }
>  
> -int instr_is_relative_branch(unsigned int instr)
> +int instr_is_relative_branch(ppc_inst instr)
>  {
>  	if (instr & BRANCH_ABSOLUTE)
>  		return 0;
> @@ -306,12 +307,12 @@ int instr_is_relative_branch(unsigned int instr)
>  	return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
>  }
>  
> -int instr_is_relative_link_branch(unsigned int instr)
> +int instr_is_relative_link_branch(ppc_inst instr)
>  {
>  	return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
>  }
>  
> -static unsigned long branch_iform_target(const unsigned int *instr)
> +static unsigned long branch_iform_target(const ppc_inst *instr)
>  {
>  	signed long imm;
>  
> @@ -327,7 +328,7 @@ static unsigned long branch_iform_target(const unsigned
> int *instr)
>  	return (unsigned long)imm;
>  }
>  
> -static unsigned long branch_bform_target(const unsigned int *instr)
> +static unsigned long branch_bform_target(const ppc_inst *instr)
>  {
>  	signed long imm;
>  
> @@ -343,7 +344,7 @@ static unsigned long branch_bform_target(const unsigned
> int *instr)
>  	return (unsigned long)imm;
>  }
>  
> -unsigned long branch_target(const unsigned int *instr)
> +unsigned long branch_target(const ppc_inst *instr)
>  {
>  	if (instr_is_branch_iform(*instr))
>  		return branch_iform_target(instr);
> @@ -353,7 +354,7 @@ unsigned long branch_target(const unsigned int *instr)
>  	return 0;
>  }
>  
> -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
> +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr)
>  {
>  	if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
>  		return branch_target(instr) == addr;
> @@ -361,7 +362,7 @@ int instr_is_branch_to_addr(const unsigned int *instr,
> unsigned long addr)
>  	return 0;
>  }
>  
> -unsigned int translate_branch(const unsigned int *dest, const unsigned int
> *src)
> +ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
>  {
>  	unsigned long target;
>  
> @@ -403,7 +404,7 @@ static void __init test_trampoline(void)
>  
>  static void __init test_branch_iform(void)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  	unsigned long addr;
>  
>  	addr = (unsigned long)&instr;
> @@ -478,11 +479,11 @@ static void __init test_branch_iform(void)
>  
>  static void __init test_create_function_call(void)
>  {
> -	unsigned int *iptr;
> +	ppc_inst *iptr;
>  	unsigned long dest;
>  
>  	/* Check we can create a function call */
> -	iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> +	iptr = (ppc_inst *)ppc_function_entry(test_trampoline);
>  	dest = ppc_function_entry(test_create_function_call);
>  	patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
>  	check(instr_is_branch_to_addr(iptr, dest));
> @@ -491,7 +492,8 @@ static void __init test_create_function_call(void)
>  static void __init test_branch_bform(void)
>  {
>  	unsigned long addr;
> -	unsigned int *iptr, instr, flags;
> +	ppc_inst *iptr, instr;
> +	unsigned int flags;
>  
>  	iptr = &instr;
>  	addr = (unsigned long)iptr;
> @@ -561,7 +563,7 @@ static void __init test_branch_bform(void)
>  static void __init test_translate_branch(void)
>  {
>  	unsigned long addr;
> -	unsigned int *p, *q;
> +	ppc_inst *p, *q;
>  	void *buf;
>  
>  	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index c077acb983a1..1d9c766a89fe 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1, long
> v2)
>   * otherwise.
>   */
>  int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> -		  unsigned int instr)
> +		  ppc_inst instr)
>  {
>  	unsigned int opcode, ra, rb, rc, rd, spr, u;
>  	unsigned long int imm;
> @@ -3101,7 +3101,7 @@ NOKPROBE_SYMBOL(emulate_loadstore);
>   * or -1 if the instruction is one that should not be stepped,
>   * such as an rfid, or a mtmsrd that would clear MSR_RI.
>   */
> -int emulate_step(struct pt_regs *regs, unsigned int instr)
> +int emulate_step(struct pt_regs *regs, ppc_inst instr)
>  {
>  	struct instruction_op op;
>  	int r, err, type;
> diff --git a/arch/powerpc/lib/test_emulate_step.c
> b/arch/powerpc/lib/test_emulate_step.c
> index 42347067739c..158efc8a0f53 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -460,7 +460,7 @@ struct compute_test {
>  	struct {
>  		char *descr;
>  		unsigned long flags;
> -		unsigned int instr;
> +		ppc_inst instr;
>  		struct pt_regs regs;
>  	} subtests[MAX_SUBTESTS + 1];
>  };
> @@ -841,7 +841,7 @@ static struct compute_test compute_tests[] = {
>  };
>  
>  static int __init emulate_compute_instr(struct pt_regs *regs,
> -					unsigned int instr)
> +					ppc_inst instr)
>  {
>  	struct instruction_op op;
>  
> @@ -859,7 +859,7 @@ static int __init emulate_compute_instr(struct pt_regs
> *regs,
>  }
>  
>  static int __init execute_compute_instr(struct pt_regs *regs,
> -					unsigned int instr)
> +					ppc_inst instr)
>  {
>  	extern int exec_instr(struct pt_regs *regs);
>  	extern s32 patch__exec_instr;
> @@ -890,7 +890,8 @@ static void __init run_tests_compute(void)
>  	unsigned long flags;
>  	struct compute_test *test;
>  	struct pt_regs *regs, exp, got;
> -	unsigned int i, j, k, instr;
> +	unsigned int i, j, k;
> +	ppc_inst instr;
>  	bool ignore_gpr, ignore_xer, ignore_ccr, passed;
>  
>  	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 7875d1a37770..a0bc442f9557 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
>  static void insert_bpts(void)
>  {
>  	int i;
> -	unsigned int instr;
> +	ppc_inst instr;
>  	struct bpt *bp;
>  
>  	bp = bpts;
> @@ -914,7 +914,7 @@ static void insert_bpts(void)
>  		patch_instruction(bp->instr, instr);
>  		if (bp->enabled & BP_CIABR)
>  			continue;
> -		if (patch_instruction((unsigned int *)bp->address,
> +		if (patch_instruction((ppc_inst *)bp->address,
>  							bpinstr) != 0) {
>  			printf("Couldn't write instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
> @@ -943,7 +943,7 @@ static void remove_bpts(void)
>  {
>  	int i;
>  	struct bpt *bp;
> -	unsigned instr;
> +	ppc_inst instr;
>  
>  	bp = bpts;
>  	for (i = 0; i < NBPTS; ++i, ++bp) {
> @@ -952,7 +952,7 @@ static void remove_bpts(void)
>  		if (mread(bp->address, &instr, 4) == 4
>  		    && instr == bpinstr
>  		    && patch_instruction(
> -			(unsigned int *)bp->address, bp->instr[0]) != 0)
> +			(ppc_inst *)bp->address, bp->instr[0]) != 0)
>  			printf("Couldn't remove breakpoint at %lx\n",
>  			       bp->address);
>  	}
> @@ -1159,7 +1159,7 @@ static int do_step(struct pt_regs *regs)
>   */
>  static int do_step(struct pt_regs *regs)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  	int stepped;
>  
>  	force_enable_xmon();
> @@ -1325,7 +1325,7 @@ csum(void)
>   */
>  static long check_bp_loc(unsigned long addr)
>  {
> -	unsigned int instr;
> +	ppc_inst instr;
>  
>  	addr &= ~3;
>  	if (!is_kernel_addr(addr)) {


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-04-01 10:32   ` Balamuruhan S
@ 2020-04-01 23:52     ` Jordan Niethe
  2020-04-02 23:44       ` Alistair Popple
  0 siblings, 1 reply; 65+ messages in thread
From: Jordan Niethe @ 2020-04-01 23:52 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, Nicholas Piggin, linuxppc-dev, Daniel Axtens

On Wed, Apr 1, 2020 at 9:32 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> > Currently unsigned ints are used to represent instructions on powerpc.
> > This has worked well as instructions have always been 4 byte words.
> > However, a future ISA version will introduce some changes to
> > instructions that mean this scheme will no longer work as well. This
> > change is Prefixed Instructions. A prefixed instruction is made up of a
> > word prefix followed by a word suffix to make an 8 byte double word
> > instruction. No matter the endianess of the system the prefix always
> > comes first. Prefixed instructions are only planned for powerpc64.
> >
> > Introduce a ppc_inst type to represent both prefixed and word
> > instructions on powerpc64 while keeping it possible to exclusively have
> > word instructions on powerpc32, A latter patch will expand the type to
> > include prefixed instructions but for now just typedef it to a u32.
> >
> > Later patches will introduce helper functions and macros for
> > manipulating the instructions so that powerpc64 and powerpc32 might
> > maintain separate type definitions.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> >  arch/powerpc/include/asm/code-patching.h | 31 +++++------
> >  arch/powerpc/include/asm/inst.h          | 53 +++++++++++++++++++
> >  arch/powerpc/include/asm/sstep.h         |  5 +-
> >  arch/powerpc/kernel/align.c              |  2 +-
> >  arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
> >  arch/powerpc/kernel/kprobes.c            |  2 +-
> >  arch/powerpc/kernel/mce_power.c          |  5 +-
> >  arch/powerpc/kernel/optprobes.c          | 10 ++--
> >  arch/powerpc/kernel/trace/ftrace.c       | 66 ++++++++++++------------
> >  arch/powerpc/kvm/emulate_loadstore.c     |  1 +
> >  arch/powerpc/lib/code-patching.c         | 54 +++++++++----------
> >  arch/powerpc/lib/sstep.c                 |  4 +-
> >  arch/powerpc/lib/test_emulate_step.c     |  9 ++--
> >  arch/powerpc/xmon/xmon.c                 | 12 ++---
> >  14 files changed, 160 insertions(+), 97 deletions(-)
> >  create mode 100644 arch/powerpc/include/asm/inst.h
> >
> > diff --git a/arch/powerpc/include/asm/code-patching.h
> > b/arch/powerpc/include/asm/code-patching.h
> > index 898b54262881..cb5106f92d67 100644
> > --- a/arch/powerpc/include/asm/code-patching.h
> > +++ b/arch/powerpc/include/asm/code-patching.h
> > @@ -11,6 +11,7 @@
> >  #include <linux/string.h>
> >  #include <linux/kallsyms.h>
> >  #include <asm/asm-compat.h>
> > +#include <asm/inst.h>
> >
> >  /* Flags for create_branch:
> >   * "b"   == create_branch(addr, target, 0);
> > @@ -22,27 +23,27 @@
> >  #define BRANCH_ABSOLUTE      0x2
> >
> >  bool is_offset_in_branch_range(long offset);
> > -unsigned int create_branch(const unsigned int *addr,
> > +ppc_inst create_branch(const ppc_inst *addr,
> >                          unsigned long target, int flags);
> > -unsigned int create_cond_branch(const unsigned int *addr,
> > +unsigned int create_cond_branch(const ppc_inst *addr,
> >                               unsigned long target, int flags);
> > -int patch_branch(unsigned int *addr, unsigned long target, int flags);
> > -int patch_instruction(unsigned int *addr, unsigned int instr);
> > -int raw_patch_instruction(unsigned int *addr, unsigned int instr);
> > +int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> > +int patch_instruction(ppc_inst *addr, ppc_inst instr);
>
> we need to handle this change for its user in epapr_paravirt.c,
Thanks, good catch.
>
> arch/powerpc/kernel/epapr_paravirt.c: In function 'early_init_dt_scan_epapr':
> arch/powerpc/kernel/epapr_paravirt.c:40:48: error: incompatible type for
> argument 2 of 'patch_instruction'
>    40 |   patch_instruction(epapr_hypercall_start + i, inst);
>       |                                                ^~~~
>       |                                                |
>       |                                                u32 {aka unsigned int}
> In file included from arch/powerpc/kernel/epapr_paravirt.c:12:
> ./arch/powerpc/include/asm/code-patching.h:31:44: note: expected 'ppc_inst'
> {aka 'struct ppc_inst'} but argument is of type 'u32' {aka 'unsigned int'}
>    31 | int patch_instruction(void *addr, ppc_inst instr);
>       |                                   ~~~~~~~~~^~~~~
> make[2]: *** [scripts/Makefile.build:268: arch/powerpc/kernel/epapr_paravirt.o]
> Error 1
> make[1]: *** [scripts/Makefile.build:505: arch/powerpc/kernel] Error 2
> make: *** [Makefile:1683: arch/powerpc] Error 2
>
>
> -- Bala
>
> > +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
> >
> >  static inline unsigned long patch_site_addr(s32 *site)
> >  {
> >       return (unsigned long)site + *site;
> >  }
> >
> > -static inline int patch_instruction_site(s32 *site, unsigned int instr)
> > +static inline int patch_instruction_site(s32 *site, ppc_inst instr)
> >  {
> > -     return patch_instruction((unsigned int *)patch_site_addr(site), instr);
> > +     return patch_instruction((ppc_inst *)patch_site_addr(site), instr);
> >  }
> >
> >  static inline int patch_branch_site(s32 *site, unsigned long target, int
> > flags)
> >  {
> > -     return patch_branch((unsigned int *)patch_site_addr(site), target,
> > flags);
> > +     return patch_branch((ppc_inst *)patch_site_addr(site), target, flags);
> >  }
> >
> >  static inline int modify_instruction(unsigned int *addr, unsigned int clr,
> > @@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site,
> > unsigned int clr, unsigned
> >       return modify_instruction((unsigned int *)patch_site_addr(site), clr,
> > set);
> >  }
> >
> > -int instr_is_relative_branch(unsigned int instr);
> > -int instr_is_relative_link_branch(unsigned int instr);
> > -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
> > -unsigned long branch_target(const unsigned int *instr);
> > -unsigned int translate_branch(const unsigned int *dest,
> > -                           const unsigned int *src);
> > -extern bool is_conditional_branch(unsigned int instr);
> > +int instr_is_relative_branch(ppc_inst instr);
> > +int instr_is_relative_link_branch(ppc_inst instr);
> > +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> > +unsigned long branch_target(const ppc_inst *instr);
> > +ppc_inst translate_branch(const ppc_inst *dest,
> > +                           const ppc_inst *src);
> > +extern bool is_conditional_branch(ppc_inst instr);
> >  #ifdef CONFIG_PPC_BOOK3E_64
> >  void __patch_exception(int exc, unsigned long addr);
> >  #define patch_exception(exc, name) do { \
> > diff --git a/arch/powerpc/include/asm/inst.h
> > b/arch/powerpc/include/asm/inst.h
> > new file mode 100644
> > index 000000000000..7c8596ee411e
> > --- /dev/null
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -0,0 +1,53 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +#ifndef _ASM_INST_H
> > +#define _ASM_INST_H
> > +
> > +/*
> > + * Instruction data type for POWER
> > + */
> > +
> > +typedef u32 ppc_inst;
> > +
> > +#define PPC_INST(x) (x)
> > +
> > +static inline int ppc_inst_len(ppc_inst x)
> > +{
> > +     return sizeof(ppc_inst);
> > +}
> > +
> > +static inline int ppc_inst_opcode(ppc_inst x)
> > +{
> > +     return x >> 26;
> > +}
> > +
> > +static inline u32 ppc_inst_word(ppc_inst x)
> > +{
> > +     return x;
> > +}
> > +
> > +static inline ppc_inst ppc_inst_read(const ppc_inst *ptr)
> > +{
> > +     return *(ppc_inst *)ptr;
> > +}
> > +
> > +static inline void ppc_inst_write(void *ptr, ppc_inst x)
> > +{
> > +     *(ppc_inst *)ptr = x;
> > +}
> > +
> > +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
> > +{
> > +     return x == y;
> > +}
> > +
> > +static inline bool ppc_inst_null(ppc_inst x)
> > +{
> > +     return x == 0;
> > +}
> > +
> > +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
> > +{
> > +     return ppc_inst_word(x) & mask;
> > +}
> > +
> > +#endif /* _ASM_INST_H */
> > diff --git a/arch/powerpc/include/asm/sstep.h
> > b/arch/powerpc/include/asm/sstep.h
> > index 769f055509c9..9353916fcba7 100644
> > --- a/arch/powerpc/include/asm/sstep.h
> > +++ b/arch/powerpc/include/asm/sstep.h
> > @@ -2,6 +2,7 @@
> >  /*
> >   * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
> >   */
> > +#include <asm/inst.h>
> >
> >  struct pt_regs;
> >
> > @@ -132,7 +133,7 @@ union vsx_reg {
> >   * otherwise.
> >   */
> >  extern int analyse_instr(struct instruction_op *op, const struct pt_regs
> > *regs,
> > -                      unsigned int instr);
> > +                      ppc_inst instr);
> >
> >  /*
> >   * Emulate an instruction that can be executed just by updating
> > @@ -149,7 +150,7 @@ 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, ppc_inst instr);
> >
> >  /*
> >   * 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..34594aaa44de 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -293,7 +293,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int
> > reg,
> >
> >  int fix_alignment(struct pt_regs *regs)
> >  {
> > -     unsigned int instr;
> > +     ppc_inst instr;
> >       struct instruction_op op;
> >       int r, type;
> >
> > diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> > b/arch/powerpc/kernel/hw_breakpoint.c
> > index 2462cd7c565c..06b97353d231 100644
> > --- a/arch/powerpc/kernel/hw_breakpoint.c
> > +++ b/arch/powerpc/kernel/hw_breakpoint.c
> > @@ -24,6 +24,7 @@
> >  #include <asm/debug.h>
> >  #include <asm/debugfs.h>
> >  #include <asm/hvcall.h>
> > +#include <asm/inst.h>
> >  #include <linux/uaccess.h>
> >
> >  /*
> > @@ -243,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size, struct
> > arch_hw_breakpoint *info)
> >  static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
> >                            struct arch_hw_breakpoint *info)
> >  {
> > -     unsigned int instr = 0;
> > +     ppc_inst instr = 0;
> >       int ret, type, size;
> >       struct instruction_op op;
> >       unsigned long addr = info->address;
> > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> > index 337516df17d4..e7205adc9820 100644
> > --- a/arch/powerpc/kernel/kprobes.c
> > +++ b/arch/powerpc/kernel/kprobes.c
> > @@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
> >  static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
> >  {
> >       int ret;
> > -     unsigned int insn = *p->ainsn.insn;
> > +     ppc_inst insn = *p->ainsn.insn;
> >
> >       /* regs->nip is also adjusted if emulate_step returns 1 */
> >       ret = emulate_step(regs, insn);
> > diff --git a/arch/powerpc/kernel/mce_power.c
> > b/arch/powerpc/kernel/mce_power.c
> > index 1cbf7f1a4e3d..e65616bb3a3e 100644
> > --- a/arch/powerpc/kernel/mce_power.c
> > +++ b/arch/powerpc/kernel/mce_power.c
> > @@ -20,6 +20,7 @@
> >  #include <asm/sstep.h>
> >  #include <asm/exception-64s.h>
> >  #include <asm/extable.h>
> > +#include <asm/inst.h>
> >
> >  /*
> >   * Convert an address related to an mm to a PFN. NOTE: we are in real
> > @@ -365,7 +366,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> > *regs, uint64_t *addr,
> >        * in real-mode is tricky and can lead to recursive
> >        * faults
> >        */
> > -     int instr;
> > +     ppc_inst instr;
> >       unsigned long pfn, instr_addr;
> >       struct instruction_op op;
> >       struct pt_regs tmp = *regs;
> > @@ -373,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> > *regs, uint64_t *addr,
> >       pfn = addr_to_pfn(regs, regs->nip);
> >       if (pfn != ULONG_MAX) {
> >               instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
> > -             instr = *(unsigned int *)(instr_addr);
> > +             instr = *(ppc_inst *)(instr_addr);
> >               if (!analyse_instr(&op, &tmp, instr)) {
> >                       pfn = addr_to_pfn(regs, op.ea);
> >                       *addr = op.ea;
> > diff --git a/arch/powerpc/kernel/optprobes.c
> > b/arch/powerpc/kernel/optprobes.c
> > index 024f7aad1952..f5e8cce438a3 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -189,8 +189,8 @@ void patch_imm64_load_insns(unsigned long val,
> > kprobe_opcode_t *addr)
> >
> >  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe
> > *p)
> >  {
> > -     kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
> > -     kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
> > +     ppc_inst branch_op_callback, branch_emulate_step;
> > +     kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
> >       long b_offset;
> >       unsigned long nip, size;
> >       int rc, i;
> > @@ -251,11 +251,11 @@ int arch_prepare_optimized_kprobe(struct
> > optimized_kprobe *op, struct kprobe *p)
> >               goto error;
> >       }
> >
> > -     branch_op_callback = create_branch((unsigned int *)buff +
> > TMPL_CALL_HDLR_IDX,
> > +     branch_op_callback = create_branch((ppc_inst *)buff +
> > TMPL_CALL_HDLR_IDX,
> >                               (unsigned long)op_callback_addr,
> >                               BRANCH_SET_LINK);
> >
> > -     branch_emulate_step = create_branch((unsigned int *)buff +
> > TMPL_EMULATE_IDX,
> > +     branch_emulate_step = create_branch((ppc_inst *)buff +
> > TMPL_EMULATE_IDX,
> >                               (unsigned long)emulate_step_addr,
> >                               BRANCH_SET_LINK);
> >
> > @@ -316,7 +316,7 @@ void arch_optimize_kprobes(struct list_head *oplist)
> >               memcpy(op->optinsn.copied_insn, op->kp.addr,
> >                                              RELATIVEJUMP_SIZE);
> >               patch_instruction(op->kp.addr,
> > -                     create_branch((unsigned int *)op->kp.addr,
> > +                     create_branch((ppc_inst *)op->kp.addr,
> >                                     (unsigned long)op->optinsn.insn, 0));
> >               list_del_init(&op->list);
> >       }
> > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > b/arch/powerpc/kernel/trace/ftrace.c
> > index 7ea0ca044b65..5787ccffb4df 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -27,6 +27,7 @@
> >  #include <asm/code-patching.h>
> >  #include <asm/ftrace.h>
> >  #include <asm/syscall.h>
> > +#include <asm/inst.h>
> >
> >
> >  #ifdef CONFIG_DYNAMIC_FTRACE
> > @@ -40,23 +41,23 @@
> >  #define      NUM_FTRACE_TRAMPS       8
> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> >
> > -static unsigned int
> > +static ppc_inst
> >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> >  {
> > -     unsigned int op;
> > +     ppc_inst op;
> >
> >       addr = ppc_function_entry((void *)addr);
> >
> >       /* if (link) set op to 'bl' else 'b' */
> > -     op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> > +     op = create_branch((ppc_inst *)ip, addr, link ? 1 : 0);
> >
> >       return op;
> >  }
> >
> >  static int
> > -ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
> > +ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
> >  {
> > -     unsigned int replaced;
> > +     ppc_inst replaced;
> >
> >       /*
> >        * Note:
> > @@ -78,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> > unsigned int new)
> >       }
> >
> >       /* replace the text with the new text */
> > -     if (patch_instruction((unsigned int *)ip, new))
> > +     if (patch_instruction((ppc_inst *)ip, new))
> >               return -EPERM;
> >
> >       return 0;
> > @@ -87,25 +88,25 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> > unsigned int new)
> >  /*
> >   * Helper functions that are the same for both PPC64 and PPC32.
> >   */
> > -static int test_24bit_addr(unsigned long ip, unsigned long addr)
> > +static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr)
> >  {
> >       addr = ppc_function_entry((void *)addr);
> >
> >       /* use the create_branch to verify that this offset can be branched */
> > -     return create_branch((unsigned int *)ip, addr, 0);
> > +     return create_branch((ppc_inst *)ip, addr, 0);
> >  }
> >
> > -static int is_bl_op(unsigned int op)
> > +static int is_bl_op(ppc_inst op)
> >  {
> >       return (op & 0xfc000003) == 0x48000001;
> >  }
> >
> > -static int is_b_op(unsigned int op)
> > +static int is_b_op(ppc_inst op)
> >  {
> >       return (op & 0xfc000003) == 0x48000000;
> >  }
> >
> > -static unsigned long find_bl_target(unsigned long ip, unsigned int op)
> > +static unsigned long find_bl_target(unsigned long ip, ppc_inst op)
> >  {
> >       int offset;
> >
> > @@ -125,7 +126,7 @@ __ftrace_make_nop(struct module *mod,
> >  {
> >       unsigned long entry, ptr, tramp;
> >       unsigned long ip = rec->ip;
> > -     unsigned int op, pop;
> > +     ppc_inst op, pop;
> >
> >       /* read where this goes */
> >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > @@ -204,7 +205,7 @@ __ftrace_make_nop(struct module *mod,
> >       }
> >  #endif /* CONFIG_MPROFILE_KERNEL */
> >
> > -     if (patch_instruction((unsigned int *)ip, pop)) {
> > +     if (patch_instruction((ppc_inst *)ip, pop)) {
> >               pr_err("Patching NOP failed.\n");
> >               return -EPERM;
> >       }
> > @@ -217,7 +218,7 @@ static int
> >  __ftrace_make_nop(struct module *mod,
> >                 struct dyn_ftrace *rec, unsigned long addr)
> >  {
> > -     unsigned int op;
> > +     ppc_inst op;
> >       unsigned int jmp[4];
> >       unsigned long ip = rec->ip;
> >       unsigned long tramp;
> > @@ -276,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
> >
> >       op = PPC_INST_NOP;
> >
> > -     if (patch_instruction((unsigned int *)ip, op))
> > +     if (patch_instruction((ppc_inst *)ip, op))
> >               return -EPERM;
> >
> >       return 0;
> > @@ -322,7 +323,8 @@ static int add_ftrace_tramp(unsigned long tramp)
> >   */
> >  static int setup_mcount_compiler_tramp(unsigned long tramp)
> >  {
> > -     int i, op;
> > +     int i;
> > +     ppc_inst op;
> >       unsigned long ptr;
> >       static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
> >
> > @@ -388,7 +390,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> > tramp)
> >  static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long
> > addr)
> >  {
> >       unsigned long tramp, ip = rec->ip;
> > -     unsigned int op;
> > +     ppc_inst op;
> >
> >       /* Read where this goes */
> >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > @@ -416,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> > *rec, unsigned long addr)
> >               }
> >       }
> >
> > -     if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) {
> > +     if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) {
> >               pr_err("Patching NOP failed.\n");
> >               return -EPERM;
> >       }
> > @@ -428,7 +430,7 @@ int ftrace_make_nop(struct module *mod,
> >                   struct dyn_ftrace *rec, unsigned long addr)
> >  {
> >       unsigned long ip = rec->ip;
> > -     unsigned int old, new;
> > +     ppc_inst old, new;
> >
> >       /*
> >        * If the calling address is more that 24 bits away,
> > @@ -481,7 +483,7 @@ int ftrace_make_nop(struct module *mod,
> >   */
> >  #ifndef CONFIG_MPROFILE_KERNEL
> >  static int
> > -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
> > +expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
> >  {
> >       /*
> >        * We expect to see:
> > @@ -510,7 +512,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> > unsigned int op1)
> >  static int
> >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> >  {
> > -     unsigned int op[2];
> > +     ppc_inst op[2];
> >       void *ip = (void *)rec->ip;
> >       unsigned long entry, ptr, tramp;
> >       struct module *mod = rec->arch.mod;
> > @@ -574,7 +576,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> > addr)
> >  static int
> >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> >  {
> > -     unsigned int op;
> > +     ppc_inst op;
> >       unsigned long ip = rec->ip;
> >
> >       /* read where this goes */
> > @@ -594,7 +596,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> > addr)
> >       }
> >
> >       /* create the branch to the trampoline */
> > -     op = create_branch((unsigned int *)ip,
> > +     op = create_branch((ppc_inst *)ip,
> >                          rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> >       if (!op) {
> >               pr_err("REL24 out of range!\n");
> > @@ -613,7 +615,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> > addr)
> >
> >  static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long
> > addr)
> >  {
> > -     unsigned int op;
> > +     ppc_inst op;
> >       void *ip = (void *)rec->ip;
> >       unsigned long tramp, entry, ptr;
> >
> > @@ -661,7 +663,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace
> > *rec, unsigned long addr)
> >  int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> >  {
> >       unsigned long ip = rec->ip;
> > -     unsigned int old, new;
> > +     ppc_inst old, new;
> >
> >       /*
> >        * If the calling address is more that 24 bits away,
> > @@ -700,7 +702,7 @@ static int
> >  __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
> >                                       unsigned long addr)
> >  {
> > -     unsigned int op;
> > +     ppc_inst op;
> >       unsigned long ip = rec->ip;
> >       unsigned long entry, ptr, tramp;
> >       struct module *mod = rec->arch.mod;
> > @@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> > long old_addr,
> >       /* The new target may be within range */
> >       if (test_24bit_addr(ip, addr)) {
> >               /* within range */
> > -             if (patch_branch((unsigned int *)ip, addr, BRANCH_SET_LINK)) {
> > +             if (patch_branch((ppc_inst *)ip, addr, BRANCH_SET_LINK)) {
> >                       pr_err("REL24 out of range!\n");
> >                       return -EINVAL;
> >               }
> > @@ -776,7 +778,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> > long old_addr,
> >       }
> >
> >       /* Ensure branch is within 24 bits */
> > -     if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> > +     if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
> >               pr_err("Branch out of range\n");
> >               return -EINVAL;
> >       }
> > @@ -794,7 +796,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> > long old_addr,
> >                       unsigned long addr)
> >  {
> >       unsigned long ip = rec->ip;
> > -     unsigned int old, new;
> > +     ppc_inst old, new;
> >
> >       /*
> >        * If the calling address is more that 24 bits away,
> > @@ -834,7 +836,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> > long old_addr,
> >  int ftrace_update_ftrace_func(ftrace_func_t func)
> >  {
> >       unsigned long ip = (unsigned long)(&ftrace_call);
> > -     unsigned int old, new;
> > +     ppc_inst old, new;
> >       int ret;
> >
> >       old = *(unsigned int *)&ftrace_call;
> > @@ -919,7 +921,7 @@ int ftrace_enable_ftrace_graph_caller(void)
> >       unsigned long ip = (unsigned long)(&ftrace_graph_call);
> >       unsigned long addr = (unsigned long)(&ftrace_graph_caller);
> >       unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> > -     unsigned int old, new;
> > +     ppc_inst old, new;
> >
> >       old = ftrace_call_replace(ip, stub, 0);
> >       new = ftrace_call_replace(ip, addr, 0);
> > @@ -932,7 +934,7 @@ int ftrace_disable_ftrace_graph_caller(void)
> >       unsigned long ip = (unsigned long)(&ftrace_graph_call);
> >       unsigned long addr = (unsigned long)(&ftrace_graph_caller);
> >       unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> > -     unsigned int old, new;
> > +     ppc_inst old, new;
> >
> >       old = ftrace_call_replace(ip, addr, 0);
> >       new = ftrace_call_replace(ip, stub, 0);
> > diff --git a/arch/powerpc/kvm/emulate_loadstore.c
> > b/arch/powerpc/kvm/emulate_loadstore.c
> > index 1139bc56e004..1c9bcbfeb924 100644
> > --- a/arch/powerpc/kvm/emulate_loadstore.c
> > +++ b/arch/powerpc/kvm/emulate_loadstore.c
> > @@ -21,6 +21,7 @@
> >  #include <asm/disassemble.h>
> >  #include <asm/ppc-opcode.h>
> >  #include <asm/sstep.h>
> > +#include <asm/inst.h>
> >  #include "timing.h"
> >  #include "trace.h"
> >
> > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > patching.c
> > index 3345f039a876..8492b9e2b8db 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -17,9 +17,10 @@
> >  #include <asm/page.h>
> >  #include <asm/code-patching.h>
> >  #include <asm/setup.h>
> > +#include <asm/inst.h>
> >
> > -static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
> > -                            unsigned int *patch_addr)
> > +static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
> > +                            ppc_inst *patch_addr)
> >  {
> >       int err = 0;
> >
> > @@ -33,7 +34,7 @@ static int __patch_instruction(unsigned int *exec_addr,
> > unsigned int instr,
> >       return 0;
> >  }
> >
> > -int raw_patch_instruction(unsigned int *addr, unsigned int instr)
> > +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
> >  {
> >       return __patch_instruction(addr, instr, addr);
> >  }
> > @@ -136,10 +137,10 @@ static inline int unmap_patch_area(unsigned long addr)
> >       return 0;
> >  }
> >
> > -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> > +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
> >  {
> >       int err;
> > -     unsigned int *patch_addr = NULL;
> > +     ppc_inst *patch_addr = NULL;
> >       unsigned long flags;
> >       unsigned long text_poke_addr;
> >       unsigned long kaddr = (unsigned long)addr;
> > @@ -176,7 +177,7 @@ static int do_patch_instruction(unsigned int *addr,
> > unsigned int instr)
> >  }
> >  #else /* !CONFIG_STRICT_KERNEL_RWX */
> >
> > -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> > +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
> >  {
> >       return raw_patch_instruction(addr, instr);
> >  }
> > @@ -194,7 +195,7 @@ int patch_instruction(unsigned int *addr, unsigned int
> > instr)
> >  }
> >  NOKPROBE_SYMBOL(patch_instruction);
> >
> > -int patch_branch(unsigned int *addr, unsigned long target, int flags)
> > +int patch_branch(ppc_inst *addr, unsigned long target, int flags)
> >  {
> >       return patch_instruction(addr, create_branch(addr, target, flags));
> >  }
> > @@ -225,7 +226,7 @@ bool is_offset_in_branch_range(long offset)
> >   * Helper to check if a given instruction is a conditional branch
> >   * Derived from the conditional checks in analyse_instr()
> >   */
> > -bool is_conditional_branch(unsigned int instr)
> > +bool is_conditional_branch(ppc_inst instr)
> >  {
> >       unsigned int opcode = instr >> 26;
> >
> > @@ -243,10 +244,10 @@ bool is_conditional_branch(unsigned int instr)
> >  }
> >  NOKPROBE_SYMBOL(is_conditional_branch);
> >
> > -unsigned int create_branch(const unsigned int *addr,
> > +ppc_inst create_branch(const ppc_inst *addr,
> >                          unsigned long target, int flags)
> >  {
> > -     unsigned int instruction;
> > +     ppc_inst instruction;
> >       long offset;
> >
> >       offset = target;
> > @@ -266,7 +267,7 @@ unsigned int create_branch(const unsigned int *addr,
> >  unsigned int create_cond_branch(const unsigned int *addr,
> >                               unsigned long target, int flags)
> >  {
> > -     unsigned int instruction;
> > +     ppc_inst instruction;
> >       long offset;
> >
> >       offset = target;
> > @@ -283,22 +284,22 @@ unsigned int create_cond_branch(const unsigned int
> > *addr,
> >       return instruction;
> >  }
> >
> > -static unsigned int branch_opcode(unsigned int instr)
> > +static unsigned int branch_opcode(ppc_inst instr)
> >  {
> >       return (instr >> 26) & 0x3F;
> >  }
> >
> > -static int instr_is_branch_iform(unsigned int instr)
> > +static int instr_is_branch_iform(ppc_inst instr)
> >  {
> >       return branch_opcode(instr) == 18;
> >  }
> >
> > -static int instr_is_branch_bform(unsigned int instr)
> > +static int instr_is_branch_bform(ppc_inst instr)
> >  {
> >       return branch_opcode(instr) == 16;
> >  }
> >
> > -int instr_is_relative_branch(unsigned int instr)
> > +int instr_is_relative_branch(ppc_inst instr)
> >  {
> >       if (instr & BRANCH_ABSOLUTE)
> >               return 0;
> > @@ -306,12 +307,12 @@ int instr_is_relative_branch(unsigned int instr)
> >       return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
> >  }
> >
> > -int instr_is_relative_link_branch(unsigned int instr)
> > +int instr_is_relative_link_branch(ppc_inst instr)
> >  {
> >       return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
> >  }
> >
> > -static unsigned long branch_iform_target(const unsigned int *instr)
> > +static unsigned long branch_iform_target(const ppc_inst *instr)
> >  {
> >       signed long imm;
> >
> > @@ -327,7 +328,7 @@ static unsigned long branch_iform_target(const unsigned
> > int *instr)
> >       return (unsigned long)imm;
> >  }
> >
> > -static unsigned long branch_bform_target(const unsigned int *instr)
> > +static unsigned long branch_bform_target(const ppc_inst *instr)
> >  {
> >       signed long imm;
> >
> > @@ -343,7 +344,7 @@ static unsigned long branch_bform_target(const unsigned
> > int *instr)
> >       return (unsigned long)imm;
> >  }
> >
> > -unsigned long branch_target(const unsigned int *instr)
> > +unsigned long branch_target(const ppc_inst *instr)
> >  {
> >       if (instr_is_branch_iform(*instr))
> >               return branch_iform_target(instr);
> > @@ -353,7 +354,7 @@ unsigned long branch_target(const unsigned int *instr)
> >       return 0;
> >  }
> >
> > -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
> > +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr)
> >  {
> >       if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
> >               return branch_target(instr) == addr;
> > @@ -361,7 +362,7 @@ int instr_is_branch_to_addr(const unsigned int *instr,
> > unsigned long addr)
> >       return 0;
> >  }
> >
> > -unsigned int translate_branch(const unsigned int *dest, const unsigned int
> > *src)
> > +ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
> >  {
> >       unsigned long target;
> >
> > @@ -403,7 +404,7 @@ static void __init test_trampoline(void)
> >
> >  static void __init test_branch_iform(void)
> >  {
> > -     unsigned int instr;
> > +     ppc_inst instr;
> >       unsigned long addr;
> >
> >       addr = (unsigned long)&instr;
> > @@ -478,11 +479,11 @@ static void __init test_branch_iform(void)
> >
> >  static void __init test_create_function_call(void)
> >  {
> > -     unsigned int *iptr;
> > +     ppc_inst *iptr;
> >       unsigned long dest;
> >
> >       /* Check we can create a function call */
> > -     iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> > +     iptr = (ppc_inst *)ppc_function_entry(test_trampoline);
> >       dest = ppc_function_entry(test_create_function_call);
> >       patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
> >       check(instr_is_branch_to_addr(iptr, dest));
> > @@ -491,7 +492,8 @@ static void __init test_create_function_call(void)
> >  static void __init test_branch_bform(void)
> >  {
> >       unsigned long addr;
> > -     unsigned int *iptr, instr, flags;
> > +     ppc_inst *iptr, instr;
> > +     unsigned int flags;
> >
> >       iptr = &instr;
> >       addr = (unsigned long)iptr;
> > @@ -561,7 +563,7 @@ static void __init test_branch_bform(void)
> >  static void __init test_translate_branch(void)
> >  {
> >       unsigned long addr;
> > -     unsigned int *p, *q;
> > +     ppc_inst *p, *q;
> >       void *buf;
> >
> >       buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > index c077acb983a1..1d9c766a89fe 100644
> > --- a/arch/powerpc/lib/sstep.c
> > +++ b/arch/powerpc/lib/sstep.c
> > @@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1, long
> > v2)
> >   * otherwise.
> >   */
> >  int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> > -               unsigned int instr)
> > +               ppc_inst instr)
> >  {
> >       unsigned int opcode, ra, rb, rc, rd, spr, u;
> >       unsigned long int imm;
> > @@ -3101,7 +3101,7 @@ NOKPROBE_SYMBOL(emulate_loadstore);
> >   * or -1 if the instruction is one that should not be stepped,
> >   * such as an rfid, or a mtmsrd that would clear MSR_RI.
> >   */
> > -int emulate_step(struct pt_regs *regs, unsigned int instr)
> > +int emulate_step(struct pt_regs *regs, ppc_inst instr)
> >  {
> >       struct instruction_op op;
> >       int r, err, type;
> > diff --git a/arch/powerpc/lib/test_emulate_step.c
> > b/arch/powerpc/lib/test_emulate_step.c
> > index 42347067739c..158efc8a0f53 100644
> > --- a/arch/powerpc/lib/test_emulate_step.c
> > +++ b/arch/powerpc/lib/test_emulate_step.c
> > @@ -460,7 +460,7 @@ struct compute_test {
> >       struct {
> >               char *descr;
> >               unsigned long flags;
> > -             unsigned int instr;
> > +             ppc_inst instr;
> >               struct pt_regs regs;
> >       } subtests[MAX_SUBTESTS + 1];
> >  };
> > @@ -841,7 +841,7 @@ static struct compute_test compute_tests[] = {
> >  };
> >
> >  static int __init emulate_compute_instr(struct pt_regs *regs,
> > -                                     unsigned int instr)
> > +                                     ppc_inst instr)
> >  {
> >       struct instruction_op op;
> >
> > @@ -859,7 +859,7 @@ static int __init emulate_compute_instr(struct pt_regs
> > *regs,
> >  }
> >
> >  static int __init execute_compute_instr(struct pt_regs *regs,
> > -                                     unsigned int instr)
> > +                                     ppc_inst instr)
> >  {
> >       extern int exec_instr(struct pt_regs *regs);
> >       extern s32 patch__exec_instr;
> > @@ -890,7 +890,8 @@ static void __init run_tests_compute(void)
> >       unsigned long flags;
> >       struct compute_test *test;
> >       struct pt_regs *regs, exp, got;
> > -     unsigned int i, j, k, instr;
> > +     unsigned int i, j, k;
> > +     ppc_inst instr;
> >       bool ignore_gpr, ignore_xer, ignore_ccr, passed;
> >
> >       for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index 7875d1a37770..a0bc442f9557 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
> >  static void insert_bpts(void)
> >  {
> >       int i;
> > -     unsigned int instr;
> > +     ppc_inst instr;
> >       struct bpt *bp;
> >
> >       bp = bpts;
> > @@ -914,7 +914,7 @@ static void insert_bpts(void)
> >               patch_instruction(bp->instr, instr);
> >               if (bp->enabled & BP_CIABR)
> >                       continue;
> > -             if (patch_instruction((unsigned int *)bp->address,
> > +             if (patch_instruction((ppc_inst *)bp->address,
> >                                                       bpinstr) != 0) {
> >                       printf("Couldn't write instruction at %lx, "
> >                              "disabling breakpoint there\n", bp->address);
> > @@ -943,7 +943,7 @@ static void remove_bpts(void)
> >  {
> >       int i;
> >       struct bpt *bp;
> > -     unsigned instr;
> > +     ppc_inst instr;
> >
> >       bp = bpts;
> >       for (i = 0; i < NBPTS; ++i, ++bp) {
> > @@ -952,7 +952,7 @@ static void remove_bpts(void)
> >               if (mread(bp->address, &instr, 4) == 4
> >                   && instr == bpinstr
> >                   && patch_instruction(
> > -                     (unsigned int *)bp->address, bp->instr[0]) != 0)
> > +                     (ppc_inst *)bp->address, bp->instr[0]) != 0)
> >                       printf("Couldn't remove breakpoint at %lx\n",
> >                              bp->address);
> >       }
> > @@ -1159,7 +1159,7 @@ static int do_step(struct pt_regs *regs)
> >   */
> >  static int do_step(struct pt_regs *regs)
> >  {
> > -     unsigned int instr;
> > +     ppc_inst instr;
> >       int stepped;
> >
> >       force_enable_xmon();
> > @@ -1325,7 +1325,7 @@ csum(void)
> >   */
> >  static long check_bp_loc(unsigned long addr)
> >  {
> > -     unsigned int instr;
> > +     ppc_inst instr;
> >
> >       addr &= ~3;
> >       if (!is_kernel_addr(addr)) {
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-04-01 23:52     ` Jordan Niethe
@ 2020-04-02 23:44       ` Alistair Popple
  2020-04-03  0:09         ` Jordan Niethe
  0 siblings, 1 reply; 65+ messages in thread
From: Alistair Popple @ 2020-04-02 23:44 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: Nicholas Piggin, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Thursday, 2 April 2020 10:52:37 AM AEDT Jordan Niethe wrote:
> On Wed, Apr 1, 2020 at 9:32 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
> > On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> > > Currently unsigned ints are used to represent instructions on powerpc.
> > > This has worked well as instructions have always been 4 byte words.
> > > However, a future ISA version will introduce some changes to
> > > instructions that mean this scheme will no longer work as well. This
> > > change is Prefixed Instructions. A prefixed instruction is made up of a
> > > word prefix followed by a word suffix to make an 8 byte double word
> > > instruction. No matter the endianess of the system the prefix always
> > > comes first. Prefixed instructions are only planned for powerpc64.
> > > 
> > > Introduce a ppc_inst type to represent both prefixed and word
> > > instructions on powerpc64 while keeping it possible to exclusively have
> > > word instructions on powerpc32, A latter patch will expand the type to
> > > include prefixed instructions but for now just typedef it to a u32.
> > > 
> > > Later patches will introduce helper functions and macros for
> > > manipulating the instructions so that powerpc64 and powerpc32 might
> > > maintain separate type definitions.
> > > 
> > > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > > ---
> > > 
> > >  arch/powerpc/include/asm/code-patching.h | 31 +++++------
> > >  arch/powerpc/include/asm/inst.h          | 53 +++++++++++++++++++
> > >  arch/powerpc/include/asm/sstep.h         |  5 +-
> > >  arch/powerpc/kernel/align.c              |  2 +-
> > >  arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
> > >  arch/powerpc/kernel/kprobes.c            |  2 +-
> > >  arch/powerpc/kernel/mce_power.c          |  5 +-
> > >  arch/powerpc/kernel/optprobes.c          | 10 ++--
> > >  arch/powerpc/kernel/trace/ftrace.c       | 66 ++++++++++++------------
> > >  arch/powerpc/kvm/emulate_loadstore.c     |  1 +
> > >  arch/powerpc/lib/code-patching.c         | 54 +++++++++----------
> > >  arch/powerpc/lib/sstep.c                 |  4 +-
> > >  arch/powerpc/lib/test_emulate_step.c     |  9 ++--
> > >  arch/powerpc/xmon/xmon.c                 | 12 ++---
> > >  14 files changed, 160 insertions(+), 97 deletions(-)
> > >  create mode 100644 arch/powerpc/include/asm/inst.h
> > > 
> > > diff --git a/arch/powerpc/include/asm/code-patching.h
> > > b/arch/powerpc/include/asm/code-patching.h
> > > index 898b54262881..cb5106f92d67 100644
> > > --- a/arch/powerpc/include/asm/code-patching.h
> > > +++ b/arch/powerpc/include/asm/code-patching.h
> > > @@ -11,6 +11,7 @@
> > > 
> > >  #include <linux/string.h>
> > >  #include <linux/kallsyms.h>
> > >  #include <asm/asm-compat.h>
> > > 
> > > +#include <asm/inst.h>
> > > 
> > >  /* Flags for create_branch:
> > >   * "b"   == create_branch(addr, target, 0);
> > > 
> > > @@ -22,27 +23,27 @@
> > > 
> > >  #define BRANCH_ABSOLUTE      0x2
> > >  
> > >  bool is_offset_in_branch_range(long offset);
> > > 
> > > -unsigned int create_branch(const unsigned int *addr,
> > > +ppc_inst create_branch(const ppc_inst *addr,
> > > 
> > >                          unsigned long target, int flags);
> > > 
> > > -unsigned int create_cond_branch(const unsigned int *addr,
> > > +unsigned int create_cond_branch(const ppc_inst *addr,
> > > 
> > >                               unsigned long target, int flags);
> > > 
> > > -int patch_branch(unsigned int *addr, unsigned long target, int flags);
> > > -int patch_instruction(unsigned int *addr, unsigned int instr);
> > > -int raw_patch_instruction(unsigned int *addr, unsigned int instr);
> > > +int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> > > +int patch_instruction(ppc_inst *addr, ppc_inst instr);
> > 
> > we need to handle this change for its user in epapr_paravirt.c,

Seeing a similar issue in kgdb.c:

In file included from /linux/include/linux/kgdb.h:20,
                 from /linux/arch/powerpc/kernel/kgdb.c:18:
/linux/arch/powerpc/kernel/kgdb.c: In function 'kgdb_arch_set_breakpoint':
/linux/arch/powerpc/include/asm/kgdb.h:30:22: error: incompatible type for argument 2 of 'patch_instruction'
 #define BREAK_INSTR  0x7d821008 /* twge r2, r2 */
                      ^~~~~~~~~~
/linux/arch/powerpc/kernel/kgdb.c:427:32: note: in expansion of macro 'BREAK_INSTR'
  err = patch_instruction(addr, BREAK_INSTR);
                                ^~~~~~~~~~~
In file included from /linux/arch/powerpc/kernel/kgdb.c:27:
/linux/arch/powerpc/include/asm/code-patching.h:31:44: note: expected 'ppc_inst' {aka 'struct ppc_inst'} but argument is of type 'int'
 int patch_instruction(void *addr, ppc_inst instr);
                                   ~~~~~~~~~^~~~~
/linux/arch/powerpc/kernel/kgdb.c: In function 'kgdb_arch_remove_breakpoint':
/linux/arch/powerpc/kernel/kgdb.c:442:32: error: incompatible type for argument 2 of 'patch_instruction'
  err = patch_instruction(addr, instr);
                                ^~~~~
In file included from /linux/arch/powerpc/kernel/kgdb.c:27:
/linux/arch/powerpc/include/asm/code-patching.h:31:44: note: expected 'ppc_inst' {aka 'struct ppc_inst'} but argument is of type 'unsigned int'
 int patch_instruction(void *addr, ppc_inst instr);
                                   ~~~~~~~~~^~~~~
make[3]: *** [/linux/scripts/Makefile.build:267: arch/powerpc/kernel/kgdb.o] Error 1

- Alistair

> Thanks, good catch.
> 
> > arch/powerpc/kernel/epapr_paravirt.c: In function
> > 'early_init_dt_scan_epapr': arch/powerpc/kernel/epapr_paravirt.c:40:48:
> > error: incompatible type for argument 2 of 'patch_instruction'
> > 
> >    40 |   patch_instruction(epapr_hypercall_start + i, inst);
> >    
> >       |                                                ^~~~
> >       |                                                
> >       |                                                u32 {aka unsigned
> >       |                                                int}
> > 
> > In file included from arch/powerpc/kernel/epapr_paravirt.c:12:
> > ./arch/powerpc/include/asm/code-patching.h:31:44: note: expected
> > 'ppc_inst'
> > {aka 'struct ppc_inst'} but argument is of type 'u32' {aka 'unsigned int'}
> > 
> >    31 | int patch_instruction(void *addr, ppc_inst instr);
> >    
> >       |                                   ~~~~~~~~~^~~~~
> > 
> > make[2]: *** [scripts/Makefile.build:268:
> > arch/powerpc/kernel/epapr_paravirt.o] Error 1
> > make[1]: *** [scripts/Makefile.build:505: arch/powerpc/kernel] Error 2
> > make: *** [Makefile:1683: arch/powerpc] Error 2
> > 
> > 
> > -- Bala
> > 
> > > +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
> > > 
> > >  static inline unsigned long patch_site_addr(s32 *site)
> > >  {
> > >  
> > >       return (unsigned long)site + *site;
> > >  
> > >  }
> > > 
> > > -static inline int patch_instruction_site(s32 *site, unsigned int instr)
> > > +static inline int patch_instruction_site(s32 *site, ppc_inst instr)
> > > 
> > >  {
> > > 
> > > -     return patch_instruction((unsigned int *)patch_site_addr(site),
> > > instr); +     return patch_instruction((ppc_inst
> > > *)patch_site_addr(site), instr);> > 
> > >  }
> > >  
> > >  static inline int patch_branch_site(s32 *site, unsigned long target,
> > >  int
> > > 
> > > flags)
> > > 
> > >  {
> > > 
> > > -     return patch_branch((unsigned int *)patch_site_addr(site), target,
> > > flags);
> > > +     return patch_branch((ppc_inst *)patch_site_addr(site), target,
> > > flags);> > 
> > >  }
> > >  
> > >  static inline int modify_instruction(unsigned int *addr, unsigned int
> > >  clr,
> > > 
> > > @@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site,
> > > unsigned int clr, unsigned
> > > 
> > >       return modify_instruction((unsigned int *)patch_site_addr(site),
> > >       clr,
> > > 
> > > set);
> > > 
> > >  }
> > > 
> > > -int instr_is_relative_branch(unsigned int instr);
> > > -int instr_is_relative_link_branch(unsigned int instr);
> > > -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long
> > > addr); -unsigned long branch_target(const unsigned int *instr);
> > > -unsigned int translate_branch(const unsigned int *dest,
> > > -                           const unsigned int *src);
> > > -extern bool is_conditional_branch(unsigned int instr);
> > > +int instr_is_relative_branch(ppc_inst instr);
> > > +int instr_is_relative_link_branch(ppc_inst instr);
> > > +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> > > +unsigned long branch_target(const ppc_inst *instr);
> > > +ppc_inst translate_branch(const ppc_inst *dest,
> > > +                           const ppc_inst *src);
> > > +extern bool is_conditional_branch(ppc_inst instr);
> > > 
> > >  #ifdef CONFIG_PPC_BOOK3E_64
> > >  void __patch_exception(int exc, unsigned long addr);
> > >  #define patch_exception(exc, name) do { \
> > > 
> > > diff --git a/arch/powerpc/include/asm/inst.h
> > > b/arch/powerpc/include/asm/inst.h
> > > new file mode 100644
> > > index 000000000000..7c8596ee411e
> > > --- /dev/null
> > > +++ b/arch/powerpc/include/asm/inst.h
> > > @@ -0,0 +1,53 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > > +#ifndef _ASM_INST_H
> > > +#define _ASM_INST_H
> > > +
> > > +/*
> > > + * Instruction data type for POWER
> > > + */
> > > +
> > > +typedef u32 ppc_inst;
> > > +
> > > +#define PPC_INST(x) (x)
> > > +
> > > +static inline int ppc_inst_len(ppc_inst x)
> > > +{
> > > +     return sizeof(ppc_inst);
> > > +}
> > > +
> > > +static inline int ppc_inst_opcode(ppc_inst x)
> > > +{
> > > +     return x >> 26;
> > > +}
> > > +
> > > +static inline u32 ppc_inst_word(ppc_inst x)
> > > +{
> > > +     return x;
> > > +}
> > > +
> > > +static inline ppc_inst ppc_inst_read(const ppc_inst *ptr)
> > > +{
> > > +     return *(ppc_inst *)ptr;
> > > +}
> > > +
> > > +static inline void ppc_inst_write(void *ptr, ppc_inst x)
> > > +{
> > > +     *(ppc_inst *)ptr = x;
> > > +}
> > > +
> > > +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
> > > +{
> > > +     return x == y;
> > > +}
> > > +
> > > +static inline bool ppc_inst_null(ppc_inst x)
> > > +{
> > > +     return x == 0;
> > > +}
> > > +
> > > +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
> > > +{
> > > +     return ppc_inst_word(x) & mask;
> > > +}
> > > +
> > > +#endif /* _ASM_INST_H */
> > > diff --git a/arch/powerpc/include/asm/sstep.h
> > > b/arch/powerpc/include/asm/sstep.h
> > > index 769f055509c9..9353916fcba7 100644
> > > --- a/arch/powerpc/include/asm/sstep.h
> > > +++ b/arch/powerpc/include/asm/sstep.h
> > > @@ -2,6 +2,7 @@
> > > 
> > >  /*
> > >  
> > >   * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
> > >   */
> > > 
> > > +#include <asm/inst.h>
> > > 
> > >  struct pt_regs;
> > > 
> > > @@ -132,7 +133,7 @@ union vsx_reg {
> > > 
> > >   * otherwise.
> > >   */
> > >  
> > >  extern int analyse_instr(struct instruction_op *op, const struct
> > >  pt_regs
> > > 
> > > *regs,
> > > -                      unsigned int instr);
> > > +                      ppc_inst instr);
> > > 
> > >  /*
> > >  
> > >   * Emulate an instruction that can be executed just by updating
> > > 
> > > @@ -149,7 +150,7 @@ 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, ppc_inst instr);
> > > 
> > >  /*
> > >  
> > >   * 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..34594aaa44de 100644
> > > --- a/arch/powerpc/kernel/align.c
> > > +++ b/arch/powerpc/kernel/align.c
> > > @@ -293,7 +293,7 @@ static int emulate_spe(struct pt_regs *regs,
> > > unsigned int reg,
> > > 
> > >  int fix_alignment(struct pt_regs *regs)
> > >  {
> > > 
> > > -     unsigned int instr;
> > > +     ppc_inst instr;
> > > 
> > >       struct instruction_op op;
> > >       int r, type;
> > > 
> > > diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> > > b/arch/powerpc/kernel/hw_breakpoint.c
> > > index 2462cd7c565c..06b97353d231 100644
> > > --- a/arch/powerpc/kernel/hw_breakpoint.c
> > > +++ b/arch/powerpc/kernel/hw_breakpoint.c
> > > @@ -24,6 +24,7 @@
> > > 
> > >  #include <asm/debug.h>
> > >  #include <asm/debugfs.h>
> > >  #include <asm/hvcall.h>
> > > 
> > > +#include <asm/inst.h>
> > > 
> > >  #include <linux/uaccess.h>
> > >  
> > >  /*
> > > 
> > > @@ -243,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size,
> > > struct
> > > arch_hw_breakpoint *info)
> > > 
> > >  static bool stepping_handler(struct pt_regs *regs, struct perf_event
> > >  *bp,
> > >  
> > >                            struct arch_hw_breakpoint *info)
> > >  
> > >  {
> > > 
> > > -     unsigned int instr = 0;
> > > +     ppc_inst instr = 0;
> > > 
> > >       int ret, type, size;
> > >       struct instruction_op op;
> > >       unsigned long addr = info->address;
> > > 
> > > diff --git a/arch/powerpc/kernel/kprobes.c
> > > b/arch/powerpc/kernel/kprobes.c
> > > index 337516df17d4..e7205adc9820 100644
> > > --- a/arch/powerpc/kernel/kprobes.c
> > > +++ b/arch/powerpc/kernel/kprobes.c
> > > @@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
> > > 
> > >  static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
> > >  {
> > >  
> > >       int ret;
> > > 
> > > -     unsigned int insn = *p->ainsn.insn;
> > > +     ppc_inst insn = *p->ainsn.insn;
> > > 
> > >       /* regs->nip is also adjusted if emulate_step returns 1 */
> > >       ret = emulate_step(regs, insn);
> > > 
> > > diff --git a/arch/powerpc/kernel/mce_power.c
> > > b/arch/powerpc/kernel/mce_power.c
> > > index 1cbf7f1a4e3d..e65616bb3a3e 100644
> > > --- a/arch/powerpc/kernel/mce_power.c
> > > +++ b/arch/powerpc/kernel/mce_power.c
> > > @@ -20,6 +20,7 @@
> > > 
> > >  #include <asm/sstep.h>
> > >  #include <asm/exception-64s.h>
> > >  #include <asm/extable.h>
> > > 
> > > +#include <asm/inst.h>
> > > 
> > >  /*
> > >  
> > >   * Convert an address related to an mm to a PFN. NOTE: we are in real
> > > 
> > > @@ -365,7 +366,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> > > *regs, uint64_t *addr,
> > > 
> > >        * in real-mode is tricky and can lead to recursive
> > >        * faults
> > >        */
> > > 
> > > -     int instr;
> > > +     ppc_inst instr;
> > > 
> > >       unsigned long pfn, instr_addr;
> > >       struct instruction_op op;
> > >       struct pt_regs tmp = *regs;
> > > 
> > > @@ -373,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> > > *regs, uint64_t *addr,
> > > 
> > >       pfn = addr_to_pfn(regs, regs->nip);
> > >       if (pfn != ULONG_MAX) {
> > >       
> > >               instr_addr = (pfn << PAGE_SHIFT) + (regs->nip &
> > >               ~PAGE_MASK);
> > > 
> > > -             instr = *(unsigned int *)(instr_addr);
> > > +             instr = *(ppc_inst *)(instr_addr);
> > > 
> > >               if (!analyse_instr(&op, &tmp, instr)) {
> > >               
> > >                       pfn = addr_to_pfn(regs, op.ea);
> > >                       *addr = op.ea;
> > > 
> > > diff --git a/arch/powerpc/kernel/optprobes.c
> > > b/arch/powerpc/kernel/optprobes.c
> > > index 024f7aad1952..f5e8cce438a3 100644
> > > --- a/arch/powerpc/kernel/optprobes.c
> > > +++ b/arch/powerpc/kernel/optprobes.c
> > > @@ -189,8 +189,8 @@ void patch_imm64_load_insns(unsigned long val,
> > > kprobe_opcode_t *addr)
> > > 
> > >  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct
> > >  kprobe> > 
> > > *p)
> > > 
> > >  {
> > > 
> > > -     kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
> > > -     kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
> > > +     ppc_inst branch_op_callback, branch_emulate_step;
> > > +     kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
> > > 
> > >       long b_offset;
> > >       unsigned long nip, size;
> > >       int rc, i;
> > > 
> > > @@ -251,11 +251,11 @@ int arch_prepare_optimized_kprobe(struct
> > > optimized_kprobe *op, struct kprobe *p)
> > > 
> > >               goto error;
> > >       
> > >       }
> > > 
> > > -     branch_op_callback = create_branch((unsigned int *)buff +
> > > TMPL_CALL_HDLR_IDX,
> > > +     branch_op_callback = create_branch((ppc_inst *)buff +
> > > TMPL_CALL_HDLR_IDX,
> > > 
> > >                               (unsigned long)op_callback_addr,
> > >                               BRANCH_SET_LINK);
> > > 
> > > -     branch_emulate_step = create_branch((unsigned int *)buff +
> > > TMPL_EMULATE_IDX,
> > > +     branch_emulate_step = create_branch((ppc_inst *)buff +
> > > TMPL_EMULATE_IDX,
> > > 
> > >                               (unsigned long)emulate_step_addr,
> > >                               BRANCH_SET_LINK);
> > > 
> > > @@ -316,7 +316,7 @@ void arch_optimize_kprobes(struct list_head *oplist)
> > > 
> > >               memcpy(op->optinsn.copied_insn, op->kp.addr,
> > >               
> > >                                              RELATIVEJUMP_SIZE);
> > >               
> > >               patch_instruction(op->kp.addr,
> > > 
> > > -                     create_branch((unsigned int *)op->kp.addr,
> > > +                     create_branch((ppc_inst *)op->kp.addr,
> > > 
> > >                                     (unsigned long)op->optinsn.insn,
> > >                                     0));
> > >               
> > >               list_del_init(&op->list);
> > >       
> > >       }
> > > 
> > > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > > b/arch/powerpc/kernel/trace/ftrace.c
> > > index 7ea0ca044b65..5787ccffb4df 100644
> > > --- a/arch/powerpc/kernel/trace/ftrace.c
> > > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > > @@ -27,6 +27,7 @@
> > > 
> > >  #include <asm/code-patching.h>
> > >  #include <asm/ftrace.h>
> > >  #include <asm/syscall.h>
> > > 
> > > +#include <asm/inst.h>
> > > 
> > >  #ifdef CONFIG_DYNAMIC_FTRACE
> > > 
> > > @@ -40,23 +41,23 @@
> > > 
> > >  #define      NUM_FTRACE_TRAMPS       8
> > >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> > > 
> > > -static unsigned int
> > > +static ppc_inst
> > > 
> > >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> > >  {
> > > 
> > > -     unsigned int op;
> > > +     ppc_inst op;
> > > 
> > >       addr = ppc_function_entry((void *)addr);
> > >       
> > >       /* if (link) set op to 'bl' else 'b' */
> > > 
> > > -     op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> > > +     op = create_branch((ppc_inst *)ip, addr, link ? 1 : 0);
> > > 
> > >       return op;
> > >  
> > >  }
> > >  
> > >  static int
> > > 
> > > -ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int
> > > new)
> > > +ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
> > > 
> > >  {
> > > 
> > > -     unsigned int replaced;
> > > +     ppc_inst replaced;
> > > 
> > >       /*
> > >       
> > >        * Note:
> > > @@ -78,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> > > unsigned int new)
> > > 
> > >       }
> > >       
> > >       /* replace the text with the new text */
> > > 
> > > -     if (patch_instruction((unsigned int *)ip, new))
> > > +     if (patch_instruction((ppc_inst *)ip, new))
> > > 
> > >               return -EPERM;
> > >       
> > >       return 0;
> > > 
> > > @@ -87,25 +88,25 @@ ftrace_modify_code(unsigned long ip, unsigned int
> > > old,
> > > unsigned int new)
> > > 
> > >  /*
> > >  
> > >   * Helper functions that are the same for both PPC64 and PPC32.
> > >   */
> > > 
> > > -static int test_24bit_addr(unsigned long ip, unsigned long addr)
> > > +static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr)
> > > 
> > >  {
> > >  
> > >       addr = ppc_function_entry((void *)addr);
> > >       
> > >       /* use the create_branch to verify that this offset can be
> > >       branched */
> > > 
> > > -     return create_branch((unsigned int *)ip, addr, 0);
> > > +     return create_branch((ppc_inst *)ip, addr, 0);
> > > 
> > >  }
> > > 
> > > -static int is_bl_op(unsigned int op)
> > > +static int is_bl_op(ppc_inst op)
> > > 
> > >  {
> > >  
> > >       return (op & 0xfc000003) == 0x48000001;
> > >  
> > >  }
> > > 
> > > -static int is_b_op(unsigned int op)
> > > +static int is_b_op(ppc_inst op)
> > > 
> > >  {
> > >  
> > >       return (op & 0xfc000003) == 0x48000000;
> > >  
> > >  }
> > > 
> > > -static unsigned long find_bl_target(unsigned long ip, unsigned int op)
> > > +static unsigned long find_bl_target(unsigned long ip, ppc_inst op)
> > > 
> > >  {
> > >  
> > >       int offset;
> > > 
> > > @@ -125,7 +126,7 @@ __ftrace_make_nop(struct module *mod,
> > > 
> > >  {
> > >  
> > >       unsigned long entry, ptr, tramp;
> > >       unsigned long ip = rec->ip;
> > > 
> > > -     unsigned int op, pop;
> > > +     ppc_inst op, pop;
> > > 
> > >       /* read where this goes */
> > >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > > 
> > > @@ -204,7 +205,7 @@ __ftrace_make_nop(struct module *mod,
> > > 
> > >       }
> > >  
> > >  #endif /* CONFIG_MPROFILE_KERNEL */
> > > 
> > > -     if (patch_instruction((unsigned int *)ip, pop)) {
> > > +     if (patch_instruction((ppc_inst *)ip, pop)) {
> > > 
> > >               pr_err("Patching NOP failed.\n");
> > >               return -EPERM;
> > >       
> > >       }
> > > 
> > > @@ -217,7 +218,7 @@ static int
> > > 
> > >  __ftrace_make_nop(struct module *mod,
> > >  
> > >                 struct dyn_ftrace *rec, unsigned long addr)
> > >  
> > >  {
> > > 
> > > -     unsigned int op;
> > > +     ppc_inst op;
> > > 
> > >       unsigned int jmp[4];
> > >       unsigned long ip = rec->ip;
> > >       unsigned long tramp;
> > > 
> > > @@ -276,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
> > > 
> > >       op = PPC_INST_NOP;
> > > 
> > > -     if (patch_instruction((unsigned int *)ip, op))
> > > +     if (patch_instruction((ppc_inst *)ip, op))
> > > 
> > >               return -EPERM;
> > >       
> > >       return 0;
> > > 
> > > @@ -322,7 +323,8 @@ static int add_ftrace_tramp(unsigned long tramp)
> > > 
> > >   */
> > >  
> > >  static int setup_mcount_compiler_tramp(unsigned long tramp)
> > >  {
> > > 
> > > -     int i, op;
> > > +     int i;
> > > +     ppc_inst op;
> > > 
> > >       unsigned long ptr;
> > >       static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
> > > 
> > > @@ -388,7 +390,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> > > tramp)
> > > 
> > >  static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned
> > >  long
> > > 
> > > addr)
> > > 
> > >  {
> > >  
> > >       unsigned long tramp, ip = rec->ip;
> > > 
> > > -     unsigned int op;
> > > +     ppc_inst op;
> > > 
> > >       /* Read where this goes */
> > >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > > 
> > > @@ -416,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct
> > > dyn_ftrace
> > > *rec, unsigned long addr)
> > > 
> > >               }
> > >       
> > >       }
> > > 
> > > -     if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) {
> > > +     if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) {
> > > 
> > >               pr_err("Patching NOP failed.\n");
> > >               return -EPERM;
> > >       
> > >       }
> > > 
> > > @@ -428,7 +430,7 @@ int ftrace_make_nop(struct module *mod,
> > > 
> > >                   struct dyn_ftrace *rec, unsigned long addr)
> > >  
> > >  {
> > >  
> > >       unsigned long ip = rec->ip;
> > > 
> > > -     unsigned int old, new;
> > > +     ppc_inst old, new;
> > > 
> > >       /*
> > >       
> > >        * If the calling address is more that 24 bits away,
> > > 
> > > @@ -481,7 +483,7 @@ int ftrace_make_nop(struct module *mod,
> > > 
> > >   */
> > >  
> > >  #ifndef CONFIG_MPROFILE_KERNEL
> > >  static int
> > > 
> > > -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
> > > +expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
> > > 
> > >  {
> > >  
> > >       /*
> > >       
> > >        * We expect to see:
> > > @@ -510,7 +512,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> > > unsigned int op1)
> > > 
> > >  static int
> > >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > >  {
> > > 
> > > -     unsigned int op[2];
> > > +     ppc_inst op[2];
> > > 
> > >       void *ip = (void *)rec->ip;
> > >       unsigned long entry, ptr, tramp;
> > >       struct module *mod = rec->arch.mod;
> > > 
> > > @@ -574,7 +576,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > long addr)
> > > 
> > >  static int
> > >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > >  {
> > > 
> > > -     unsigned int op;
> > > +     ppc_inst op;
> > > 
> > >       unsigned long ip = rec->ip;
> > >       
> > >       /* read where this goes */
> > > 
> > > @@ -594,7 +596,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > long addr)
> > > 
> > >       }
> > >       
> > >       /* create the branch to the trampoline */
> > > 
> > > -     op = create_branch((unsigned int *)ip,
> > > +     op = create_branch((ppc_inst *)ip,
> > > 
> > >                          rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> > >       
> > >       if (!op) {
> > >       
> > >               pr_err("REL24 out of range!\n");
> > > 
> > > @@ -613,7 +615,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > long addr)
> > > 
> > >  static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned
> > >  long
> > > 
> > > addr)
> > > 
> > >  {
> > > 
> > > -     unsigned int op;
> > > +     ppc_inst op;
> > > 
> > >       void *ip = (void *)rec->ip;
> > >       unsigned long tramp, entry, ptr;
> > > 
> > > @@ -661,7 +663,7 @@ static int __ftrace_make_call_kernel(struct
> > > dyn_ftrace
> > > *rec, unsigned long addr)
> > > 
> > >  int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > >  {
> > >  
> > >       unsigned long ip = rec->ip;
> > > 
> > > -     unsigned int old, new;
> > > +     ppc_inst old, new;
> > > 
> > >       /*
> > >       
> > >        * If the calling address is more that 24 bits away,
> > > 
> > > @@ -700,7 +702,7 @@ static int
> > > 
> > >  __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
> > >  
> > >                                       unsigned long addr)
> > >  
> > >  {
> > > 
> > > -     unsigned int op;
> > > +     ppc_inst op;
> > > 
> > >       unsigned long ip = rec->ip;
> > >       unsigned long entry, ptr, tramp;
> > >       struct module *mod = rec->arch.mod;
> > > 
> > > @@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec,
> > > unsigned
> > > long old_addr,
> > > 
> > >       /* The new target may be within range */
> > >       if (test_24bit_addr(ip, addr)) {
> > >       
> > >               /* within range */
> > > 
> > > -             if (patch_branch((unsigned int *)ip, addr,
> > > BRANCH_SET_LINK)) { +             if (patch_branch((ppc_inst *)ip,
> > > addr, BRANCH_SET_LINK)) {> > 
> > >                       pr_err("REL24 out of range!\n");
> > >                       return -EINVAL;
> > >               
> > >               }
> > > 
> > > @@ -776,7 +778,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec,
> > > unsigned
> > > long old_addr,
> > > 
> > >       }
> > >       
> > >       /* Ensure branch is within 24 bits */
> > > 
> > > -     if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> > > +     if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
> > > 
> > >               pr_err("Branch out of range\n");
> > >               return -EINVAL;
> > >       
> > >       }
> > > 
> > > @@ -794,7 +796,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec,
> > > unsigned
> > > long old_addr,
> > > 
> > >                       unsigned long addr)
> > >  
> > >  {
> > >  
> > >       unsigned long ip = rec->ip;
> > > 
> > > -     unsigned int old, new;
> > > +     ppc_inst old, new;
> > > 
> > >       /*
> > >       
> > >        * If the calling address is more that 24 bits away,
> > > 
> > > @@ -834,7 +836,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec,
> > > unsigned
> > > long old_addr,
> > > 
> > >  int ftrace_update_ftrace_func(ftrace_func_t func)
> > >  {
> > >  
> > >       unsigned long ip = (unsigned long)(&ftrace_call);
> > > 
> > > -     unsigned int old, new;
> > > +     ppc_inst old, new;
> > > 
> > >       int ret;
> > >       
> > >       old = *(unsigned int *)&ftrace_call;
> > > 
> > > @@ -919,7 +921,7 @@ int ftrace_enable_ftrace_graph_caller(void)
> > > 
> > >       unsigned long ip = (unsigned long)(&ftrace_graph_call);
> > >       unsigned long addr = (unsigned long)(&ftrace_graph_caller);
> > >       unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> > > 
> > > -     unsigned int old, new;
> > > +     ppc_inst old, new;
> > > 
> > >       old = ftrace_call_replace(ip, stub, 0);
> > >       new = ftrace_call_replace(ip, addr, 0);
> > > 
> > > @@ -932,7 +934,7 @@ int ftrace_disable_ftrace_graph_caller(void)
> > > 
> > >       unsigned long ip = (unsigned long)(&ftrace_graph_call);
> > >       unsigned long addr = (unsigned long)(&ftrace_graph_caller);
> > >       unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> > > 
> > > -     unsigned int old, new;
> > > +     ppc_inst old, new;
> > > 
> > >       old = ftrace_call_replace(ip, addr, 0);
> > >       new = ftrace_call_replace(ip, stub, 0);
> > > 
> > > diff --git a/arch/powerpc/kvm/emulate_loadstore.c
> > > b/arch/powerpc/kvm/emulate_loadstore.c
> > > index 1139bc56e004..1c9bcbfeb924 100644
> > > --- a/arch/powerpc/kvm/emulate_loadstore.c
> > > +++ b/arch/powerpc/kvm/emulate_loadstore.c
> > > @@ -21,6 +21,7 @@
> > > 
> > >  #include <asm/disassemble.h>
> > >  #include <asm/ppc-opcode.h>
> > >  #include <asm/sstep.h>
> > > 
> > > +#include <asm/inst.h>
> > > 
> > >  #include "timing.h"
> > >  #include "trace.h"
> > > 
> > > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > > patching.c
> > > index 3345f039a876..8492b9e2b8db 100644
> > > --- a/arch/powerpc/lib/code-patching.c
> > > +++ b/arch/powerpc/lib/code-patching.c
> > > @@ -17,9 +17,10 @@
> > > 
> > >  #include <asm/page.h>
> > >  #include <asm/code-patching.h>
> > >  #include <asm/setup.h>
> > > 
> > > +#include <asm/inst.h>
> > > 
> > > -static int __patch_instruction(unsigned int *exec_addr, unsigned int
> > > instr, -                            unsigned int *patch_addr)
> > > +static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
> > > +                            ppc_inst *patch_addr)
> > > 
> > >  {
> > >  
> > >       int err = 0;
> > > 
> > > @@ -33,7 +34,7 @@ static int __patch_instruction(unsigned int
> > > *exec_addr,
> > > unsigned int instr,
> > > 
> > >       return 0;
> > >  
> > >  }
> > > 
> > > -int raw_patch_instruction(unsigned int *addr, unsigned int instr)
> > > +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       return __patch_instruction(addr, instr, addr);
> > >  
> > >  }
> > > 
> > > @@ -136,10 +137,10 @@ static inline int unmap_patch_area(unsigned long
> > > addr)> > 
> > >       return 0;
> > >  
> > >  }
> > > 
> > > -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> > > +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       int err;
> > > 
> > > -     unsigned int *patch_addr = NULL;
> > > +     ppc_inst *patch_addr = NULL;
> > > 
> > >       unsigned long flags;
> > >       unsigned long text_poke_addr;
> > >       unsigned long kaddr = (unsigned long)addr;
> > > 
> > > @@ -176,7 +177,7 @@ static int do_patch_instruction(unsigned int *addr,
> > > unsigned int instr)
> > > 
> > >  }
> > >  #else /* !CONFIG_STRICT_KERNEL_RWX */
> > > 
> > > -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> > > +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       return raw_patch_instruction(addr, instr);
> > >  
> > >  }
> > > 
> > > @@ -194,7 +195,7 @@ int patch_instruction(unsigned int *addr, unsigned
> > > int
> > > instr)
> > > 
> > >  }
> > >  NOKPROBE_SYMBOL(patch_instruction);
> > > 
> > > -int patch_branch(unsigned int *addr, unsigned long target, int flags)
> > > +int patch_branch(ppc_inst *addr, unsigned long target, int flags)
> > > 
> > >  {
> > >  
> > >       return patch_instruction(addr, create_branch(addr, target,
> > >       flags));
> > >  
> > >  }
> > > 
> > > @@ -225,7 +226,7 @@ bool is_offset_in_branch_range(long offset)
> > > 
> > >   * Helper to check if a given instruction is a conditional branch
> > >   * Derived from the conditional checks in analyse_instr()
> > >   */
> > > 
> > > -bool is_conditional_branch(unsigned int instr)
> > > +bool is_conditional_branch(ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       unsigned int opcode = instr >> 26;
> > > 
> > > @@ -243,10 +244,10 @@ bool is_conditional_branch(unsigned int instr)
> > > 
> > >  }
> > >  NOKPROBE_SYMBOL(is_conditional_branch);
> > > 
> > > -unsigned int create_branch(const unsigned int *addr,
> > > +ppc_inst create_branch(const ppc_inst *addr,
> > > 
> > >                          unsigned long target, int flags)
> > >  
> > >  {
> > > 
> > > -     unsigned int instruction;
> > > +     ppc_inst instruction;
> > > 
> > >       long offset;
> > >       
> > >       offset = target;
> > > 
> > > @@ -266,7 +267,7 @@ unsigned int create_branch(const unsigned int *addr,
> > > 
> > >  unsigned int create_cond_branch(const unsigned int *addr,
> > >  
> > >                               unsigned long target, int flags)
> > >  
> > >  {
> > > 
> > > -     unsigned int instruction;
> > > +     ppc_inst instruction;
> > > 
> > >       long offset;
> > >       
> > >       offset = target;
> > > 
> > > @@ -283,22 +284,22 @@ unsigned int create_cond_branch(const unsigned int
> > > *addr,
> > > 
> > >       return instruction;
> > >  
> > >  }
> > > 
> > > -static unsigned int branch_opcode(unsigned int instr)
> > > +static unsigned int branch_opcode(ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       return (instr >> 26) & 0x3F;
> > >  
> > >  }
> > > 
> > > -static int instr_is_branch_iform(unsigned int instr)
> > > +static int instr_is_branch_iform(ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       return branch_opcode(instr) == 18;
> > >  
> > >  }
> > > 
> > > -static int instr_is_branch_bform(unsigned int instr)
> > > +static int instr_is_branch_bform(ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       return branch_opcode(instr) == 16;
> > >  
> > >  }
> > > 
> > > -int instr_is_relative_branch(unsigned int instr)
> > > +int instr_is_relative_branch(ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       if (instr & BRANCH_ABSOLUTE)
> > >       
> > >               return 0;
> > > 
> > > @@ -306,12 +307,12 @@ int instr_is_relative_branch(unsigned int instr)
> > > 
> > >       return instr_is_branch_iform(instr) ||
> > >       instr_is_branch_bform(instr);
> > >  
> > >  }
> > > 
> > > -int instr_is_relative_link_branch(unsigned int instr)
> > > +int instr_is_relative_link_branch(ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       return instr_is_relative_branch(instr) && (instr &
> > >       BRANCH_SET_LINK);
> > >  
> > >  }
> > > 
> > > -static unsigned long branch_iform_target(const unsigned int *instr)
> > > +static unsigned long branch_iform_target(const ppc_inst *instr)
> > > 
> > >  {
> > >  
> > >       signed long imm;
> > > 
> > > @@ -327,7 +328,7 @@ static unsigned long branch_iform_target(const
> > > unsigned
> > > int *instr)
> > > 
> > >       return (unsigned long)imm;
> > >  
> > >  }
> > > 
> > > -static unsigned long branch_bform_target(const unsigned int *instr)
> > > +static unsigned long branch_bform_target(const ppc_inst *instr)
> > > 
> > >  {
> > >  
> > >       signed long imm;
> > > 
> > > @@ -343,7 +344,7 @@ static unsigned long branch_bform_target(const
> > > unsigned
> > > int *instr)
> > > 
> > >       return (unsigned long)imm;
> > >  
> > >  }
> > > 
> > > -unsigned long branch_target(const unsigned int *instr)
> > > +unsigned long branch_target(const ppc_inst *instr)
> > > 
> > >  {
> > >  
> > >       if (instr_is_branch_iform(*instr))
> > >       
> > >               return branch_iform_target(instr);
> > > 
> > > @@ -353,7 +354,7 @@ unsigned long branch_target(const unsigned int
> > > *instr)
> > > 
> > >       return 0;
> > >  
> > >  }
> > > 
> > > -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long
> > > addr)
> > > +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr)
> > > 
> > >  {
> > >  
> > >       if (instr_is_branch_iform(*instr) ||
> > >       instr_is_branch_bform(*instr))
> > >       
> > >               return branch_target(instr) == addr;
> > > 
> > > @@ -361,7 +362,7 @@ int instr_is_branch_to_addr(const unsigned int
> > > *instr,
> > > unsigned long addr)
> > > 
> > >       return 0;
> > >  
> > >  }
> > > 
> > > -unsigned int translate_branch(const unsigned int *dest, const unsigned
> > > int
> > > *src)
> > > +ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
> > > 
> > >  {
> > >  
> > >       unsigned long target;
> > > 
> > > @@ -403,7 +404,7 @@ static void __init test_trampoline(void)
> > > 
> > >  static void __init test_branch_iform(void)
> > >  {
> > > 
> > > -     unsigned int instr;
> > > +     ppc_inst instr;
> > > 
> > >       unsigned long addr;
> > >       
> > >       addr = (unsigned long)&instr;
> > > 
> > > @@ -478,11 +479,11 @@ static void __init test_branch_iform(void)
> > > 
> > >  static void __init test_create_function_call(void)
> > >  {
> > > 
> > > -     unsigned int *iptr;
> > > +     ppc_inst *iptr;
> > > 
> > >       unsigned long dest;
> > >       
> > >       /* Check we can create a function call */
> > > 
> > > -     iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> > > +     iptr = (ppc_inst *)ppc_function_entry(test_trampoline);
> > > 
> > >       dest = ppc_function_entry(test_create_function_call);
> > >       patch_instruction(iptr, create_branch(iptr, dest,
> > >       BRANCH_SET_LINK));
> > >       check(instr_is_branch_to_addr(iptr, dest));
> > > 
> > > @@ -491,7 +492,8 @@ static void __init test_create_function_call(void)
> > > 
> > >  static void __init test_branch_bform(void)
> > >  {
> > >  
> > >       unsigned long addr;
> > > 
> > > -     unsigned int *iptr, instr, flags;
> > > +     ppc_inst *iptr, instr;
> > > +     unsigned int flags;
> > > 
> > >       iptr = &instr;
> > >       addr = (unsigned long)iptr;
> > > 
> > > @@ -561,7 +563,7 @@ static void __init test_branch_bform(void)
> > > 
> > >  static void __init test_translate_branch(void)
> > >  {
> > >  
> > >       unsigned long addr;
> > > 
> > > -     unsigned int *p, *q;
> > > +     ppc_inst *p, *q;
> > > 
> > >       void *buf;
> > >       
> > >       buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> > > 
> > > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > > index c077acb983a1..1d9c766a89fe 100644
> > > --- a/arch/powerpc/lib/sstep.c
> > > +++ b/arch/powerpc/lib/sstep.c
> > > @@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1,
> > > long
> > > v2)
> > > 
> > >   * otherwise.
> > >   */
> > >  
> > >  int analyse_instr(struct instruction_op *op, const struct pt_regs
> > >  *regs,
> > > 
> > > -               unsigned int instr)
> > > +               ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       unsigned int opcode, ra, rb, rc, rd, spr, u;
> > >       unsigned long int imm;
> > > 
> > > @@ -3101,7 +3101,7 @@ NOKPROBE_SYMBOL(emulate_loadstore);
> > > 
> > >   * or -1 if the instruction is one that should not be stepped,
> > >   * such as an rfid, or a mtmsrd that would clear MSR_RI.
> > >   */
> > > 
> > > -int emulate_step(struct pt_regs *regs, unsigned int instr)
> > > +int emulate_step(struct pt_regs *regs, ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       struct instruction_op op;
> > >       int r, err, type;
> > > 
> > > diff --git a/arch/powerpc/lib/test_emulate_step.c
> > > b/arch/powerpc/lib/test_emulate_step.c
> > > index 42347067739c..158efc8a0f53 100644
> > > --- a/arch/powerpc/lib/test_emulate_step.c
> > > +++ b/arch/powerpc/lib/test_emulate_step.c
> > > @@ -460,7 +460,7 @@ struct compute_test {
> > > 
> > >       struct {
> > >       
> > >               char *descr;
> > >               unsigned long flags;
> > > 
> > > -             unsigned int instr;
> > > +             ppc_inst instr;
> > > 
> > >               struct pt_regs regs;
> > >       
> > >       } subtests[MAX_SUBTESTS + 1];
> > >  
> > >  };
> > > 
> > > @@ -841,7 +841,7 @@ static struct compute_test compute_tests[] = {
> > > 
> > >  };
> > >  
> > >  static int __init emulate_compute_instr(struct pt_regs *regs,
> > > 
> > > -                                     unsigned int instr)
> > > +                                     ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       struct instruction_op op;
> > > 
> > > @@ -859,7 +859,7 @@ static int __init emulate_compute_instr(struct
> > > pt_regs
> > > *regs,
> > > 
> > >  }
> > >  
> > >  static int __init execute_compute_instr(struct pt_regs *regs,
> > > 
> > > -                                     unsigned int instr)
> > > +                                     ppc_inst instr)
> > > 
> > >  {
> > >  
> > >       extern int exec_instr(struct pt_regs *regs);
> > >       extern s32 patch__exec_instr;
> > > 
> > > @@ -890,7 +890,8 @@ static void __init run_tests_compute(void)
> > > 
> > >       unsigned long flags;
> > >       struct compute_test *test;
> > >       struct pt_regs *regs, exp, got;
> > > 
> > > -     unsigned int i, j, k, instr;
> > > +     unsigned int i, j, k;
> > > +     ppc_inst instr;
> > > 
> > >       bool ignore_gpr, ignore_xer, ignore_ccr, passed;
> > >       
> > >       for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
> > > 
> > > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > > index 7875d1a37770..a0bc442f9557 100644
> > > --- a/arch/powerpc/xmon/xmon.c
> > > +++ b/arch/powerpc/xmon/xmon.c
> > > @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
> > > 
> > >  static void insert_bpts(void)
> > >  {
> > >  
> > >       int i;
> > > 
> > > -     unsigned int instr;
> > > +     ppc_inst instr;
> > > 
> > >       struct bpt *bp;
> > >       
> > >       bp = bpts;
> > > 
> > > @@ -914,7 +914,7 @@ static void insert_bpts(void)
> > > 
> > >               patch_instruction(bp->instr, instr);
> > >               if (bp->enabled & BP_CIABR)
> > >               
> > >                       continue;
> > > 
> > > -             if (patch_instruction((unsigned int *)bp->address,
> > > +             if (patch_instruction((ppc_inst *)bp->address,
> > > 
> > >                                                       bpinstr) != 0) {
> > >                       
> > >                       printf("Couldn't write instruction at %lx, "
> > >                       
> > >                              "disabling breakpoint there\n",
> > >                              bp->address);
> > > 
> > > @@ -943,7 +943,7 @@ static void remove_bpts(void)
> > > 
> > >  {
> > >  
> > >       int i;
> > >       struct bpt *bp;
> > > 
> > > -     unsigned instr;
> > > +     ppc_inst instr;
> > > 
> > >       bp = bpts;
> > >       for (i = 0; i < NBPTS; ++i, ++bp) {
> > > 
> > > @@ -952,7 +952,7 @@ static void remove_bpts(void)
> > > 
> > >               if (mread(bp->address, &instr, 4) == 4
> > >               
> > >                   && instr == bpinstr
> > >                   && patch_instruction(
> > > 
> > > -                     (unsigned int *)bp->address, bp->instr[0]) != 0)
> > > +                     (ppc_inst *)bp->address, bp->instr[0]) != 0)
> > > 
> > >                       printf("Couldn't remove breakpoint at %lx\n",
> > >                       
> > >                              bp->address);
> > >       
> > >       }
> > > 
> > > @@ -1159,7 +1159,7 @@ static int do_step(struct pt_regs *regs)
> > > 
> > >   */
> > >  
> > >  static int do_step(struct pt_regs *regs)
> > >  {
> > > 
> > > -     unsigned int instr;
> > > +     ppc_inst instr;
> > > 
> > >       int stepped;
> > >       
> > >       force_enable_xmon();
> > > 
> > > @@ -1325,7 +1325,7 @@ csum(void)
> > > 
> > >   */
> > >  
> > >  static long check_bp_loc(unsigned long addr)
> > >  {
> > > 
> > > -     unsigned int instr;
> > > +     ppc_inst instr;
> > > 
> > >       addr &= ~3;
> > >       if (!is_kernel_addr(addr)) {





^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/16] powerpc: Use a datatype for instructions
  2020-04-02 23:44       ` Alistair Popple
@ 2020-04-03  0:09         ` Jordan Niethe
  0 siblings, 0 replies; 65+ messages in thread
From: Jordan Niethe @ 2020-04-03  0:09 UTC (permalink / raw)
  To: Alistair Popple
  Cc: Nicholas Piggin, Balamuruhan S, linuxppc-dev, Daniel Axtens

On Fri, Apr 3, 2020 at 10:45 AM Alistair Popple <alistair@popple.id.au> wrote:
>
> On Thursday, 2 April 2020 10:52:37 AM AEDT Jordan Niethe wrote:
> > On Wed, Apr 1, 2020 at 9:32 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
> > > On Fri, 2020-03-20 at 16:17 +1100, Jordan Niethe wrote:
> > > > Currently unsigned ints are used to represent instructions on powerpc.
> > > > This has worked well as instructions have always been 4 byte words.
> > > > However, a future ISA version will introduce some changes to
> > > > instructions that mean this scheme will no longer work as well. This
> > > > change is Prefixed Instructions. A prefixed instruction is made up of a
> > > > word prefix followed by a word suffix to make an 8 byte double word
> > > > instruction. No matter the endianess of the system the prefix always
> > > > comes first. Prefixed instructions are only planned for powerpc64.
> > > >
> > > > Introduce a ppc_inst type to represent both prefixed and word
> > > > instructions on powerpc64 while keeping it possible to exclusively have
> > > > word instructions on powerpc32, A latter patch will expand the type to
> > > > include prefixed instructions but for now just typedef it to a u32.
> > > >
> > > > Later patches will introduce helper functions and macros for
> > > > manipulating the instructions so that powerpc64 and powerpc32 might
> > > > maintain separate type definitions.
> > > >
> > > > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > > > ---
> > > >
> > > >  arch/powerpc/include/asm/code-patching.h | 31 +++++------
> > > >  arch/powerpc/include/asm/inst.h          | 53 +++++++++++++++++++
> > > >  arch/powerpc/include/asm/sstep.h         |  5 +-
> > > >  arch/powerpc/kernel/align.c              |  2 +-
> > > >  arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
> > > >  arch/powerpc/kernel/kprobes.c            |  2 +-
> > > >  arch/powerpc/kernel/mce_power.c          |  5 +-
> > > >  arch/powerpc/kernel/optprobes.c          | 10 ++--
> > > >  arch/powerpc/kernel/trace/ftrace.c       | 66 ++++++++++++------------
> > > >  arch/powerpc/kvm/emulate_loadstore.c     |  1 +
> > > >  arch/powerpc/lib/code-patching.c         | 54 +++++++++----------
> > > >  arch/powerpc/lib/sstep.c                 |  4 +-
> > > >  arch/powerpc/lib/test_emulate_step.c     |  9 ++--
> > > >  arch/powerpc/xmon/xmon.c                 | 12 ++---
> > > >  14 files changed, 160 insertions(+), 97 deletions(-)
> > > >  create mode 100644 arch/powerpc/include/asm/inst.h
> > > >
> > > > diff --git a/arch/powerpc/include/asm/code-patching.h
> > > > b/arch/powerpc/include/asm/code-patching.h
> > > > index 898b54262881..cb5106f92d67 100644
> > > > --- a/arch/powerpc/include/asm/code-patching.h
> > > > +++ b/arch/powerpc/include/asm/code-patching.h
> > > > @@ -11,6 +11,7 @@
> > > >
> > > >  #include <linux/string.h>
> > > >  #include <linux/kallsyms.h>
> > > >  #include <asm/asm-compat.h>
> > > >
> > > > +#include <asm/inst.h>
> > > >
> > > >  /* Flags for create_branch:
> > > >   * "b"   == create_branch(addr, target, 0);
> > > >
> > > > @@ -22,27 +23,27 @@
> > > >
> > > >  #define BRANCH_ABSOLUTE      0x2
> > > >
> > > >  bool is_offset_in_branch_range(long offset);
> > > >
> > > > -unsigned int create_branch(const unsigned int *addr,
> > > > +ppc_inst create_branch(const ppc_inst *addr,
> > > >
> > > >                          unsigned long target, int flags);
> > > >
> > > > -unsigned int create_cond_branch(const unsigned int *addr,
> > > > +unsigned int create_cond_branch(const ppc_inst *addr,
> > > >
> > > >                               unsigned long target, int flags);
> > > >
> > > > -int patch_branch(unsigned int *addr, unsigned long target, int flags);
> > > > -int patch_instruction(unsigned int *addr, unsigned int instr);
> > > > -int raw_patch_instruction(unsigned int *addr, unsigned int instr);
> > > > +int patch_branch(ppc_inst *addr, unsigned long target, int flags);
> > > > +int patch_instruction(ppc_inst *addr, ppc_inst instr);
> > >
> > > we need to handle this change for its user in epapr_paravirt.c,
>
> Seeing a similar issue in kgdb.c:
>
> In file included from /linux/include/linux/kgdb.h:20,
>                  from /linux/arch/powerpc/kernel/kgdb.c:18:
> /linux/arch/powerpc/kernel/kgdb.c: In function 'kgdb_arch_set_breakpoint':
> /linux/arch/powerpc/include/asm/kgdb.h:30:22: error: incompatible type for argument 2 of 'patch_instruction'
>  #define BREAK_INSTR  0x7d821008 /* twge r2, r2 */
>                       ^~~~~~~~~~
> /linux/arch/powerpc/kernel/kgdb.c:427:32: note: in expansion of macro 'BREAK_INSTR'
>   err = patch_instruction(addr, BREAK_INSTR);
>                                 ^~~~~~~~~~~
> In file included from /linux/arch/powerpc/kernel/kgdb.c:27:
> /linux/arch/powerpc/include/asm/code-patching.h:31:44: note: expected 'ppc_inst' {aka 'struct ppc_inst'} but argument is of type 'int'
>  int patch_instruction(void *addr, ppc_inst instr);
>                                    ~~~~~~~~~^~~~~
> /linux/arch/powerpc/kernel/kgdb.c: In function 'kgdb_arch_remove_breakpoint':
> /linux/arch/powerpc/kernel/kgdb.c:442:32: error: incompatible type for argument 2 of 'patch_instruction'
>   err = patch_instruction(addr, instr);
>                                 ^~~~~
> In file included from /linux/arch/powerpc/kernel/kgdb.c:27:
> /linux/arch/powerpc/include/asm/code-patching.h:31:44: note: expected 'ppc_inst' {aka 'struct ppc_inst'} but argument is of type 'unsigned int'
>  int patch_instruction(void *addr, ppc_inst instr);
>                                    ~~~~~~~~~^~~~~
> make[3]: *** [/linux/scripts/Makefile.build:267: arch/powerpc/kernel/kgdb.o] Error 1
>
> - Alistair
Thanks, I will check it out.
>
> > Thanks, good catch.
> >
> > > arch/powerpc/kernel/epapr_paravirt.c: In function
> > > 'early_init_dt_scan_epapr': arch/powerpc/kernel/epapr_paravirt.c:40:48:
> > > error: incompatible type for argument 2 of 'patch_instruction'
> > >
> > >    40 |   patch_instruction(epapr_hypercall_start + i, inst);
> > >
> > >       |                                                ^~~~
> > >       |
> > >       |                                                u32 {aka unsigned
> > >       |                                                int}
> > >
> > > In file included from arch/powerpc/kernel/epapr_paravirt.c:12:
> > > ./arch/powerpc/include/asm/code-patching.h:31:44: note: expected
> > > 'ppc_inst'
> > > {aka 'struct ppc_inst'} but argument is of type 'u32' {aka 'unsigned int'}
> > >
> > >    31 | int patch_instruction(void *addr, ppc_inst instr);
> > >
> > >       |                                   ~~~~~~~~~^~~~~
> > >
> > > make[2]: *** [scripts/Makefile.build:268:
> > > arch/powerpc/kernel/epapr_paravirt.o] Error 1
> > > make[1]: *** [scripts/Makefile.build:505: arch/powerpc/kernel] Error 2
> > > make: *** [Makefile:1683: arch/powerpc] Error 2
> > >
> > >
> > > -- Bala
> > >
> > > > +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr);
> > > >
> > > >  static inline unsigned long patch_site_addr(s32 *site)
> > > >  {
> > > >
> > > >       return (unsigned long)site + *site;
> > > >
> > > >  }
> > > >
> > > > -static inline int patch_instruction_site(s32 *site, unsigned int instr)
> > > > +static inline int patch_instruction_site(s32 *site, ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > > -     return patch_instruction((unsigned int *)patch_site_addr(site),
> > > > instr); +     return patch_instruction((ppc_inst
> > > > *)patch_site_addr(site), instr);> >
> > > >  }
> > > >
> > > >  static inline int patch_branch_site(s32 *site, unsigned long target,
> > > >  int
> > > >
> > > > flags)
> > > >
> > > >  {
> > > >
> > > > -     return patch_branch((unsigned int *)patch_site_addr(site), target,
> > > > flags);
> > > > +     return patch_branch((ppc_inst *)patch_site_addr(site), target,
> > > > flags);> >
> > > >  }
> > > >
> > > >  static inline int modify_instruction(unsigned int *addr, unsigned int
> > > >  clr,
> > > >
> > > > @@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site,
> > > > unsigned int clr, unsigned
> > > >
> > > >       return modify_instruction((unsigned int *)patch_site_addr(site),
> > > >       clr,
> > > >
> > > > set);
> > > >
> > > >  }
> > > >
> > > > -int instr_is_relative_branch(unsigned int instr);
> > > > -int instr_is_relative_link_branch(unsigned int instr);
> > > > -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long
> > > > addr); -unsigned long branch_target(const unsigned int *instr);
> > > > -unsigned int translate_branch(const unsigned int *dest,
> > > > -                           const unsigned int *src);
> > > > -extern bool is_conditional_branch(unsigned int instr);
> > > > +int instr_is_relative_branch(ppc_inst instr);
> > > > +int instr_is_relative_link_branch(ppc_inst instr);
> > > > +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr);
> > > > +unsigned long branch_target(const ppc_inst *instr);
> > > > +ppc_inst translate_branch(const ppc_inst *dest,
> > > > +                           const ppc_inst *src);
> > > > +extern bool is_conditional_branch(ppc_inst instr);
> > > >
> > > >  #ifdef CONFIG_PPC_BOOK3E_64
> > > >  void __patch_exception(int exc, unsigned long addr);
> > > >  #define patch_exception(exc, name) do { \
> > > >
> > > > diff --git a/arch/powerpc/include/asm/inst.h
> > > > b/arch/powerpc/include/asm/inst.h
> > > > new file mode 100644
> > > > index 000000000000..7c8596ee411e
> > > > --- /dev/null
> > > > +++ b/arch/powerpc/include/asm/inst.h
> > > > @@ -0,0 +1,53 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > > > +#ifndef _ASM_INST_H
> > > > +#define _ASM_INST_H
> > > > +
> > > > +/*
> > > > + * Instruction data type for POWER
> > > > + */
> > > > +
> > > > +typedef u32 ppc_inst;
> > > > +
> > > > +#define PPC_INST(x) (x)
> > > > +
> > > > +static inline int ppc_inst_len(ppc_inst x)
> > > > +{
> > > > +     return sizeof(ppc_inst);
> > > > +}
> > > > +
> > > > +static inline int ppc_inst_opcode(ppc_inst x)
> > > > +{
> > > > +     return x >> 26;
> > > > +}
> > > > +
> > > > +static inline u32 ppc_inst_word(ppc_inst x)
> > > > +{
> > > > +     return x;
> > > > +}
> > > > +
> > > > +static inline ppc_inst ppc_inst_read(const ppc_inst *ptr)
> > > > +{
> > > > +     return *(ppc_inst *)ptr;
> > > > +}
> > > > +
> > > > +static inline void ppc_inst_write(void *ptr, ppc_inst x)
> > > > +{
> > > > +     *(ppc_inst *)ptr = x;
> > > > +}
> > > > +
> > > > +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y)
> > > > +{
> > > > +     return x == y;
> > > > +}
> > > > +
> > > > +static inline bool ppc_inst_null(ppc_inst x)
> > > > +{
> > > > +     return x == 0;
> > > > +}
> > > > +
> > > > +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask)
> > > > +{
> > > > +     return ppc_inst_word(x) & mask;
> > > > +}
> > > > +
> > > > +#endif /* _ASM_INST_H */
> > > > diff --git a/arch/powerpc/include/asm/sstep.h
> > > > b/arch/powerpc/include/asm/sstep.h
> > > > index 769f055509c9..9353916fcba7 100644
> > > > --- a/arch/powerpc/include/asm/sstep.h
> > > > +++ b/arch/powerpc/include/asm/sstep.h
> > > > @@ -2,6 +2,7 @@
> > > >
> > > >  /*
> > > >
> > > >   * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
> > > >   */
> > > >
> > > > +#include <asm/inst.h>
> > > >
> > > >  struct pt_regs;
> > > >
> > > > @@ -132,7 +133,7 @@ union vsx_reg {
> > > >
> > > >   * otherwise.
> > > >   */
> > > >
> > > >  extern int analyse_instr(struct instruction_op *op, const struct
> > > >  pt_regs
> > > >
> > > > *regs,
> > > > -                      unsigned int instr);
> > > > +                      ppc_inst instr);
> > > >
> > > >  /*
> > > >
> > > >   * Emulate an instruction that can be executed just by updating
> > > >
> > > > @@ -149,7 +150,7 @@ 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, ppc_inst instr);
> > > >
> > > >  /*
> > > >
> > > >   * 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..34594aaa44de 100644
> > > > --- a/arch/powerpc/kernel/align.c
> > > > +++ b/arch/powerpc/kernel/align.c
> > > > @@ -293,7 +293,7 @@ static int emulate_spe(struct pt_regs *regs,
> > > > unsigned int reg,
> > > >
> > > >  int fix_alignment(struct pt_regs *regs)
> > > >  {
> > > >
> > > > -     unsigned int instr;
> > > > +     ppc_inst instr;
> > > >
> > > >       struct instruction_op op;
> > > >       int r, type;
> > > >
> > > > diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> > > > b/arch/powerpc/kernel/hw_breakpoint.c
> > > > index 2462cd7c565c..06b97353d231 100644
> > > > --- a/arch/powerpc/kernel/hw_breakpoint.c
> > > > +++ b/arch/powerpc/kernel/hw_breakpoint.c
> > > > @@ -24,6 +24,7 @@
> > > >
> > > >  #include <asm/debug.h>
> > > >  #include <asm/debugfs.h>
> > > >  #include <asm/hvcall.h>
> > > >
> > > > +#include <asm/inst.h>
> > > >
> > > >  #include <linux/uaccess.h>
> > > >
> > > >  /*
> > > >
> > > > @@ -243,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size,
> > > > struct
> > > > arch_hw_breakpoint *info)
> > > >
> > > >  static bool stepping_handler(struct pt_regs *regs, struct perf_event
> > > >  *bp,
> > > >
> > > >                            struct arch_hw_breakpoint *info)
> > > >
> > > >  {
> > > >
> > > > -     unsigned int instr = 0;
> > > > +     ppc_inst instr = 0;
> > > >
> > > >       int ret, type, size;
> > > >       struct instruction_op op;
> > > >       unsigned long addr = info->address;
> > > >
> > > > diff --git a/arch/powerpc/kernel/kprobes.c
> > > > b/arch/powerpc/kernel/kprobes.c
> > > > index 337516df17d4..e7205adc9820 100644
> > > > --- a/arch/powerpc/kernel/kprobes.c
> > > > +++ b/arch/powerpc/kernel/kprobes.c
> > > > @@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
> > > >
> > > >  static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
> > > >  {
> > > >
> > > >       int ret;
> > > >
> > > > -     unsigned int insn = *p->ainsn.insn;
> > > > +     ppc_inst insn = *p->ainsn.insn;
> > > >
> > > >       /* regs->nip is also adjusted if emulate_step returns 1 */
> > > >       ret = emulate_step(regs, insn);
> > > >
> > > > diff --git a/arch/powerpc/kernel/mce_power.c
> > > > b/arch/powerpc/kernel/mce_power.c
> > > > index 1cbf7f1a4e3d..e65616bb3a3e 100644
> > > > --- a/arch/powerpc/kernel/mce_power.c
> > > > +++ b/arch/powerpc/kernel/mce_power.c
> > > > @@ -20,6 +20,7 @@
> > > >
> > > >  #include <asm/sstep.h>
> > > >  #include <asm/exception-64s.h>
> > > >  #include <asm/extable.h>
> > > >
> > > > +#include <asm/inst.h>
> > > >
> > > >  /*
> > > >
> > > >   * Convert an address related to an mm to a PFN. NOTE: we are in real
> > > >
> > > > @@ -365,7 +366,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> > > > *regs, uint64_t *addr,
> > > >
> > > >        * in real-mode is tricky and can lead to recursive
> > > >        * faults
> > > >        */
> > > >
> > > > -     int instr;
> > > > +     ppc_inst instr;
> > > >
> > > >       unsigned long pfn, instr_addr;
> > > >       struct instruction_op op;
> > > >       struct pt_regs tmp = *regs;
> > > >
> > > > @@ -373,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs
> > > > *regs, uint64_t *addr,
> > > >
> > > >       pfn = addr_to_pfn(regs, regs->nip);
> > > >       if (pfn != ULONG_MAX) {
> > > >
> > > >               instr_addr = (pfn << PAGE_SHIFT) + (regs->nip &
> > > >               ~PAGE_MASK);
> > > >
> > > > -             instr = *(unsigned int *)(instr_addr);
> > > > +             instr = *(ppc_inst *)(instr_addr);
> > > >
> > > >               if (!analyse_instr(&op, &tmp, instr)) {
> > > >
> > > >                       pfn = addr_to_pfn(regs, op.ea);
> > > >                       *addr = op.ea;
> > > >
> > > > diff --git a/arch/powerpc/kernel/optprobes.c
> > > > b/arch/powerpc/kernel/optprobes.c
> > > > index 024f7aad1952..f5e8cce438a3 100644
> > > > --- a/arch/powerpc/kernel/optprobes.c
> > > > +++ b/arch/powerpc/kernel/optprobes.c
> > > > @@ -189,8 +189,8 @@ void patch_imm64_load_insns(unsigned long val,
> > > > kprobe_opcode_t *addr)
> > > >
> > > >  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct
> > > >  kprobe> >
> > > > *p)
> > > >
> > > >  {
> > > >
> > > > -     kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
> > > > -     kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
> > > > +     ppc_inst branch_op_callback, branch_emulate_step;
> > > > +     kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
> > > >
> > > >       long b_offset;
> > > >       unsigned long nip, size;
> > > >       int rc, i;
> > > >
> > > > @@ -251,11 +251,11 @@ int arch_prepare_optimized_kprobe(struct
> > > > optimized_kprobe *op, struct kprobe *p)
> > > >
> > > >               goto error;
> > > >
> > > >       }
> > > >
> > > > -     branch_op_callback = create_branch((unsigned int *)buff +
> > > > TMPL_CALL_HDLR_IDX,
> > > > +     branch_op_callback = create_branch((ppc_inst *)buff +
> > > > TMPL_CALL_HDLR_IDX,
> > > >
> > > >                               (unsigned long)op_callback_addr,
> > > >                               BRANCH_SET_LINK);
> > > >
> > > > -     branch_emulate_step = create_branch((unsigned int *)buff +
> > > > TMPL_EMULATE_IDX,
> > > > +     branch_emulate_step = create_branch((ppc_inst *)buff +
> > > > TMPL_EMULATE_IDX,
> > > >
> > > >                               (unsigned long)emulate_step_addr,
> > > >                               BRANCH_SET_LINK);
> > > >
> > > > @@ -316,7 +316,7 @@ void arch_optimize_kprobes(struct list_head *oplist)
> > > >
> > > >               memcpy(op->optinsn.copied_insn, op->kp.addr,
> > > >
> > > >                                              RELATIVEJUMP_SIZE);
> > > >
> > > >               patch_instruction(op->kp.addr,
> > > >
> > > > -                     create_branch((unsigned int *)op->kp.addr,
> > > > +                     create_branch((ppc_inst *)op->kp.addr,
> > > >
> > > >                                     (unsigned long)op->optinsn.insn,
> > > >                                     0));
> > > >
> > > >               list_del_init(&op->list);
> > > >
> > > >       }
> > > >
> > > > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > > > b/arch/powerpc/kernel/trace/ftrace.c
> > > > index 7ea0ca044b65..5787ccffb4df 100644
> > > > --- a/arch/powerpc/kernel/trace/ftrace.c
> > > > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > > > @@ -27,6 +27,7 @@
> > > >
> > > >  #include <asm/code-patching.h>
> > > >  #include <asm/ftrace.h>
> > > >  #include <asm/syscall.h>
> > > >
> > > > +#include <asm/inst.h>
> > > >
> > > >  #ifdef CONFIG_DYNAMIC_FTRACE
> > > >
> > > > @@ -40,23 +41,23 @@
> > > >
> > > >  #define      NUM_FTRACE_TRAMPS       8
> > > >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> > > >
> > > > -static unsigned int
> > > > +static ppc_inst
> > > >
> > > >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> > > >  {
> > > >
> > > > -     unsigned int op;
> > > > +     ppc_inst op;
> > > >
> > > >       addr = ppc_function_entry((void *)addr);
> > > >
> > > >       /* if (link) set op to 'bl' else 'b' */
> > > >
> > > > -     op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> > > > +     op = create_branch((ppc_inst *)ip, addr, link ? 1 : 0);
> > > >
> > > >       return op;
> > > >
> > > >  }
> > > >
> > > >  static int
> > > >
> > > > -ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int
> > > > new)
> > > > +ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new)
> > > >
> > > >  {
> > > >
> > > > -     unsigned int replaced;
> > > > +     ppc_inst replaced;
> > > >
> > > >       /*
> > > >
> > > >        * Note:
> > > > @@ -78,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> > > > unsigned int new)
> > > >
> > > >       }
> > > >
> > > >       /* replace the text with the new text */
> > > >
> > > > -     if (patch_instruction((unsigned int *)ip, new))
> > > > +     if (patch_instruction((ppc_inst *)ip, new))
> > > >
> > > >               return -EPERM;
> > > >
> > > >       return 0;
> > > >
> > > > @@ -87,25 +88,25 @@ ftrace_modify_code(unsigned long ip, unsigned int
> > > > old,
> > > > unsigned int new)
> > > >
> > > >  /*
> > > >
> > > >   * Helper functions that are the same for both PPC64 and PPC32.
> > > >   */
> > > >
> > > > -static int test_24bit_addr(unsigned long ip, unsigned long addr)
> > > > +static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr)
> > > >
> > > >  {
> > > >
> > > >       addr = ppc_function_entry((void *)addr);
> > > >
> > > >       /* use the create_branch to verify that this offset can be
> > > >       branched */
> > > >
> > > > -     return create_branch((unsigned int *)ip, addr, 0);
> > > > +     return create_branch((ppc_inst *)ip, addr, 0);
> > > >
> > > >  }
> > > >
> > > > -static int is_bl_op(unsigned int op)
> > > > +static int is_bl_op(ppc_inst op)
> > > >
> > > >  {
> > > >
> > > >       return (op & 0xfc000003) == 0x48000001;
> > > >
> > > >  }
> > > >
> > > > -static int is_b_op(unsigned int op)
> > > > +static int is_b_op(ppc_inst op)
> > > >
> > > >  {
> > > >
> > > >       return (op & 0xfc000003) == 0x48000000;
> > > >
> > > >  }
> > > >
> > > > -static unsigned long find_bl_target(unsigned long ip, unsigned int op)
> > > > +static unsigned long find_bl_target(unsigned long ip, ppc_inst op)
> > > >
> > > >  {
> > > >
> > > >       int offset;
> > > >
> > > > @@ -125,7 +126,7 @@ __ftrace_make_nop(struct module *mod,
> > > >
> > > >  {
> > > >
> > > >       unsigned long entry, ptr, tramp;
> > > >       unsigned long ip = rec->ip;
> > > >
> > > > -     unsigned int op, pop;
> > > > +     ppc_inst op, pop;
> > > >
> > > >       /* read where this goes */
> > > >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > > >
> > > > @@ -204,7 +205,7 @@ __ftrace_make_nop(struct module *mod,
> > > >
> > > >       }
> > > >
> > > >  #endif /* CONFIG_MPROFILE_KERNEL */
> > > >
> > > > -     if (patch_instruction((unsigned int *)ip, pop)) {
> > > > +     if (patch_instruction((ppc_inst *)ip, pop)) {
> > > >
> > > >               pr_err("Patching NOP failed.\n");
> > > >               return -EPERM;
> > > >
> > > >       }
> > > >
> > > > @@ -217,7 +218,7 @@ static int
> > > >
> > > >  __ftrace_make_nop(struct module *mod,
> > > >
> > > >                 struct dyn_ftrace *rec, unsigned long addr)
> > > >
> > > >  {
> > > >
> > > > -     unsigned int op;
> > > > +     ppc_inst op;
> > > >
> > > >       unsigned int jmp[4];
> > > >       unsigned long ip = rec->ip;
> > > >       unsigned long tramp;
> > > >
> > > > @@ -276,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
> > > >
> > > >       op = PPC_INST_NOP;
> > > >
> > > > -     if (patch_instruction((unsigned int *)ip, op))
> > > > +     if (patch_instruction((ppc_inst *)ip, op))
> > > >
> > > >               return -EPERM;
> > > >
> > > >       return 0;
> > > >
> > > > @@ -322,7 +323,8 @@ static int add_ftrace_tramp(unsigned long tramp)
> > > >
> > > >   */
> > > >
> > > >  static int setup_mcount_compiler_tramp(unsigned long tramp)
> > > >  {
> > > >
> > > > -     int i, op;
> > > > +     int i;
> > > > +     ppc_inst op;
> > > >
> > > >       unsigned long ptr;
> > > >       static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
> > > >
> > > > @@ -388,7 +390,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> > > > tramp)
> > > >
> > > >  static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned
> > > >  long
> > > >
> > > > addr)
> > > >
> > > >  {
> > > >
> > > >       unsigned long tramp, ip = rec->ip;
> > > >
> > > > -     unsigned int op;
> > > > +     ppc_inst op;
> > > >
> > > >       /* Read where this goes */
> > > >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > > >
> > > > @@ -416,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct
> > > > dyn_ftrace
> > > > *rec, unsigned long addr)
> > > >
> > > >               }
> > > >
> > > >       }
> > > >
> > > > -     if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) {
> > > > +     if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) {
> > > >
> > > >               pr_err("Patching NOP failed.\n");
> > > >               return -EPERM;
> > > >
> > > >       }
> > > >
> > > > @@ -428,7 +430,7 @@ int ftrace_make_nop(struct module *mod,
> > > >
> > > >                   struct dyn_ftrace *rec, unsigned long addr)
> > > >
> > > >  {
> > > >
> > > >       unsigned long ip = rec->ip;
> > > >
> > > > -     unsigned int old, new;
> > > > +     ppc_inst old, new;
> > > >
> > > >       /*
> > > >
> > > >        * If the calling address is more that 24 bits away,
> > > >
> > > > @@ -481,7 +483,7 @@ int ftrace_make_nop(struct module *mod,
> > > >
> > > >   */
> > > >
> > > >  #ifndef CONFIG_MPROFILE_KERNEL
> > > >  static int
> > > >
> > > > -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
> > > > +expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1)
> > > >
> > > >  {
> > > >
> > > >       /*
> > > >
> > > >        * We expect to see:
> > > > @@ -510,7 +512,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> > > > unsigned int op1)
> > > >
> > > >  static int
> > > >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > > >  {
> > > >
> > > > -     unsigned int op[2];
> > > > +     ppc_inst op[2];
> > > >
> > > >       void *ip = (void *)rec->ip;
> > > >       unsigned long entry, ptr, tramp;
> > > >       struct module *mod = rec->arch.mod;
> > > >
> > > > @@ -574,7 +576,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > > long addr)
> > > >
> > > >  static int
> > > >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > > >  {
> > > >
> > > > -     unsigned int op;
> > > > +     ppc_inst op;
> > > >
> > > >       unsigned long ip = rec->ip;
> > > >
> > > >       /* read where this goes */
> > > >
> > > > @@ -594,7 +596,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > > long addr)
> > > >
> > > >       }
> > > >
> > > >       /* create the branch to the trampoline */
> > > >
> > > > -     op = create_branch((unsigned int *)ip,
> > > > +     op = create_branch((ppc_inst *)ip,
> > > >
> > > >                          rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> > > >
> > > >       if (!op) {
> > > >
> > > >               pr_err("REL24 out of range!\n");
> > > >
> > > > @@ -613,7 +615,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > > long addr)
> > > >
> > > >  static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned
> > > >  long
> > > >
> > > > addr)
> > > >
> > > >  {
> > > >
> > > > -     unsigned int op;
> > > > +     ppc_inst op;
> > > >
> > > >       void *ip = (void *)rec->ip;
> > > >       unsigned long tramp, entry, ptr;
> > > >
> > > > @@ -661,7 +663,7 @@ static int __ftrace_make_call_kernel(struct
> > > > dyn_ftrace
> > > > *rec, unsigned long addr)
> > > >
> > > >  int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > > >  {
> > > >
> > > >       unsigned long ip = rec->ip;
> > > >
> > > > -     unsigned int old, new;
> > > > +     ppc_inst old, new;
> > > >
> > > >       /*
> > > >
> > > >        * If the calling address is more that 24 bits away,
> > > >
> > > > @@ -700,7 +702,7 @@ static int
> > > >
> > > >  __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
> > > >
> > > >                                       unsigned long addr)
> > > >
> > > >  {
> > > >
> > > > -     unsigned int op;
> > > > +     ppc_inst op;
> > > >
> > > >       unsigned long ip = rec->ip;
> > > >       unsigned long entry, ptr, tramp;
> > > >       struct module *mod = rec->arch.mod;
> > > >
> > > > @@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec,
> > > > unsigned
> > > > long old_addr,
> > > >
> > > >       /* The new target may be within range */
> > > >       if (test_24bit_addr(ip, addr)) {
> > > >
> > > >               /* within range */
> > > >
> > > > -             if (patch_branch((unsigned int *)ip, addr,
> > > > BRANCH_SET_LINK)) { +             if (patch_branch((ppc_inst *)ip,
> > > > addr, BRANCH_SET_LINK)) {> >
> > > >                       pr_err("REL24 out of range!\n");
> > > >                       return -EINVAL;
> > > >
> > > >               }
> > > >
> > > > @@ -776,7 +778,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec,
> > > > unsigned
> > > > long old_addr,
> > > >
> > > >       }
> > > >
> > > >       /* Ensure branch is within 24 bits */
> > > >
> > > > -     if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> > > > +     if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
> > > >
> > > >               pr_err("Branch out of range\n");
> > > >               return -EINVAL;
> > > >
> > > >       }
> > > >
> > > > @@ -794,7 +796,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec,
> > > > unsigned
> > > > long old_addr,
> > > >
> > > >                       unsigned long addr)
> > > >
> > > >  {
> > > >
> > > >       unsigned long ip = rec->ip;
> > > >
> > > > -     unsigned int old, new;
> > > > +     ppc_inst old, new;
> > > >
> > > >       /*
> > > >
> > > >        * If the calling address is more that 24 bits away,
> > > >
> > > > @@ -834,7 +836,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec,
> > > > unsigned
> > > > long old_addr,
> > > >
> > > >  int ftrace_update_ftrace_func(ftrace_func_t func)
> > > >  {
> > > >
> > > >       unsigned long ip = (unsigned long)(&ftrace_call);
> > > >
> > > > -     unsigned int old, new;
> > > > +     ppc_inst old, new;
> > > >
> > > >       int ret;
> > > >
> > > >       old = *(unsigned int *)&ftrace_call;
> > > >
> > > > @@ -919,7 +921,7 @@ int ftrace_enable_ftrace_graph_caller(void)
> > > >
> > > >       unsigned long ip = (unsigned long)(&ftrace_graph_call);
> > > >       unsigned long addr = (unsigned long)(&ftrace_graph_caller);
> > > >       unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> > > >
> > > > -     unsigned int old, new;
> > > > +     ppc_inst old, new;
> > > >
> > > >       old = ftrace_call_replace(ip, stub, 0);
> > > >       new = ftrace_call_replace(ip, addr, 0);
> > > >
> > > > @@ -932,7 +934,7 @@ int ftrace_disable_ftrace_graph_caller(void)
> > > >
> > > >       unsigned long ip = (unsigned long)(&ftrace_graph_call);
> > > >       unsigned long addr = (unsigned long)(&ftrace_graph_caller);
> > > >       unsigned long stub = (unsigned long)(&ftrace_graph_stub);
> > > >
> > > > -     unsigned int old, new;
> > > > +     ppc_inst old, new;
> > > >
> > > >       old = ftrace_call_replace(ip, addr, 0);
> > > >       new = ftrace_call_replace(ip, stub, 0);
> > > >
> > > > diff --git a/arch/powerpc/kvm/emulate_loadstore.c
> > > > b/arch/powerpc/kvm/emulate_loadstore.c
> > > > index 1139bc56e004..1c9bcbfeb924 100644
> > > > --- a/arch/powerpc/kvm/emulate_loadstore.c
> > > > +++ b/arch/powerpc/kvm/emulate_loadstore.c
> > > > @@ -21,6 +21,7 @@
> > > >
> > > >  #include <asm/disassemble.h>
> > > >  #include <asm/ppc-opcode.h>
> > > >  #include <asm/sstep.h>
> > > >
> > > > +#include <asm/inst.h>
> > > >
> > > >  #include "timing.h"
> > > >  #include "trace.h"
> > > >
> > > > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > > > patching.c
> > > > index 3345f039a876..8492b9e2b8db 100644
> > > > --- a/arch/powerpc/lib/code-patching.c
> > > > +++ b/arch/powerpc/lib/code-patching.c
> > > > @@ -17,9 +17,10 @@
> > > >
> > > >  #include <asm/page.h>
> > > >  #include <asm/code-patching.h>
> > > >  #include <asm/setup.h>
> > > >
> > > > +#include <asm/inst.h>
> > > >
> > > > -static int __patch_instruction(unsigned int *exec_addr, unsigned int
> > > > instr, -                            unsigned int *patch_addr)
> > > > +static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr,
> > > > +                            ppc_inst *patch_addr)
> > > >
> > > >  {
> > > >
> > > >       int err = 0;
> > > >
> > > > @@ -33,7 +34,7 @@ static int __patch_instruction(unsigned int
> > > > *exec_addr,
> > > > unsigned int instr,
> > > >
> > > >       return 0;
> > > >
> > > >  }
> > > >
> > > > -int raw_patch_instruction(unsigned int *addr, unsigned int instr)
> > > > +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       return __patch_instruction(addr, instr, addr);
> > > >
> > > >  }
> > > >
> > > > @@ -136,10 +137,10 @@ static inline int unmap_patch_area(unsigned long
> > > > addr)> >
> > > >       return 0;
> > > >
> > > >  }
> > > >
> > > > -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> > > > +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       int err;
> > > >
> > > > -     unsigned int *patch_addr = NULL;
> > > > +     ppc_inst *patch_addr = NULL;
> > > >
> > > >       unsigned long flags;
> > > >       unsigned long text_poke_addr;
> > > >       unsigned long kaddr = (unsigned long)addr;
> > > >
> > > > @@ -176,7 +177,7 @@ static int do_patch_instruction(unsigned int *addr,
> > > > unsigned int instr)
> > > >
> > > >  }
> > > >  #else /* !CONFIG_STRICT_KERNEL_RWX */
> > > >
> > > > -static int do_patch_instruction(unsigned int *addr, unsigned int instr)
> > > > +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       return raw_patch_instruction(addr, instr);
> > > >
> > > >  }
> > > >
> > > > @@ -194,7 +195,7 @@ int patch_instruction(unsigned int *addr, unsigned
> > > > int
> > > > instr)
> > > >
> > > >  }
> > > >  NOKPROBE_SYMBOL(patch_instruction);
> > > >
> > > > -int patch_branch(unsigned int *addr, unsigned long target, int flags)
> > > > +int patch_branch(ppc_inst *addr, unsigned long target, int flags)
> > > >
> > > >  {
> > > >
> > > >       return patch_instruction(addr, create_branch(addr, target,
> > > >       flags));
> > > >
> > > >  }
> > > >
> > > > @@ -225,7 +226,7 @@ bool is_offset_in_branch_range(long offset)
> > > >
> > > >   * Helper to check if a given instruction is a conditional branch
> > > >   * Derived from the conditional checks in analyse_instr()
> > > >   */
> > > >
> > > > -bool is_conditional_branch(unsigned int instr)
> > > > +bool is_conditional_branch(ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       unsigned int opcode = instr >> 26;
> > > >
> > > > @@ -243,10 +244,10 @@ bool is_conditional_branch(unsigned int instr)
> > > >
> > > >  }
> > > >  NOKPROBE_SYMBOL(is_conditional_branch);
> > > >
> > > > -unsigned int create_branch(const unsigned int *addr,
> > > > +ppc_inst create_branch(const ppc_inst *addr,
> > > >
> > > >                          unsigned long target, int flags)
> > > >
> > > >  {
> > > >
> > > > -     unsigned int instruction;
> > > > +     ppc_inst instruction;
> > > >
> > > >       long offset;
> > > >
> > > >       offset = target;
> > > >
> > > > @@ -266,7 +267,7 @@ unsigned int create_branch(const unsigned int *addr,
> > > >
> > > >  unsigned int create_cond_branch(const unsigned int *addr,
> > > >
> > > >                               unsigned long target, int flags)
> > > >
> > > >  {
> > > >
> > > > -     unsigned int instruction;
> > > > +     ppc_inst instruction;
> > > >
> > > >       long offset;
> > > >
> > > >       offset = target;
> > > >
> > > > @@ -283,22 +284,22 @@ unsigned int create_cond_branch(const unsigned int
> > > > *addr,
> > > >
> > > >       return instruction;
> > > >
> > > >  }
> > > >
> > > > -static unsigned int branch_opcode(unsigned int instr)
> > > > +static unsigned int branch_opcode(ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       return (instr >> 26) & 0x3F;
> > > >
> > > >  }
> > > >
> > > > -static int instr_is_branch_iform(unsigned int instr)
> > > > +static int instr_is_branch_iform(ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       return branch_opcode(instr) == 18;
> > > >
> > > >  }
> > > >
> > > > -static int instr_is_branch_bform(unsigned int instr)
> > > > +static int instr_is_branch_bform(ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       return branch_opcode(instr) == 16;
> > > >
> > > >  }
> > > >
> > > > -int instr_is_relative_branch(unsigned int instr)
> > > > +int instr_is_relative_branch(ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       if (instr & BRANCH_ABSOLUTE)
> > > >
> > > >               return 0;
> > > >
> > > > @@ -306,12 +307,12 @@ int instr_is_relative_branch(unsigned int instr)
> > > >
> > > >       return instr_is_branch_iform(instr) ||
> > > >       instr_is_branch_bform(instr);
> > > >
> > > >  }
> > > >
> > > > -int instr_is_relative_link_branch(unsigned int instr)
> > > > +int instr_is_relative_link_branch(ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       return instr_is_relative_branch(instr) && (instr &
> > > >       BRANCH_SET_LINK);
> > > >
> > > >  }
> > > >
> > > > -static unsigned long branch_iform_target(const unsigned int *instr)
> > > > +static unsigned long branch_iform_target(const ppc_inst *instr)
> > > >
> > > >  {
> > > >
> > > >       signed long imm;
> > > >
> > > > @@ -327,7 +328,7 @@ static unsigned long branch_iform_target(const
> > > > unsigned
> > > > int *instr)
> > > >
> > > >       return (unsigned long)imm;
> > > >
> > > >  }
> > > >
> > > > -static unsigned long branch_bform_target(const unsigned int *instr)
> > > > +static unsigned long branch_bform_target(const ppc_inst *instr)
> > > >
> > > >  {
> > > >
> > > >       signed long imm;
> > > >
> > > > @@ -343,7 +344,7 @@ static unsigned long branch_bform_target(const
> > > > unsigned
> > > > int *instr)
> > > >
> > > >       return (unsigned long)imm;
> > > >
> > > >  }
> > > >
> > > > -unsigned long branch_target(const unsigned int *instr)
> > > > +unsigned long branch_target(const ppc_inst *instr)
> > > >
> > > >  {
> > > >
> > > >       if (instr_is_branch_iform(*instr))
> > > >
> > > >               return branch_iform_target(instr);
> > > >
> > > > @@ -353,7 +354,7 @@ unsigned long branch_target(const unsigned int
> > > > *instr)
> > > >
> > > >       return 0;
> > > >
> > > >  }
> > > >
> > > > -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long
> > > > addr)
> > > > +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr)
> > > >
> > > >  {
> > > >
> > > >       if (instr_is_branch_iform(*instr) ||
> > > >       instr_is_branch_bform(*instr))
> > > >
> > > >               return branch_target(instr) == addr;
> > > >
> > > > @@ -361,7 +362,7 @@ int instr_is_branch_to_addr(const unsigned int
> > > > *instr,
> > > > unsigned long addr)
> > > >
> > > >       return 0;
> > > >
> > > >  }
> > > >
> > > > -unsigned int translate_branch(const unsigned int *dest, const unsigned
> > > > int
> > > > *src)
> > > > +ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src)
> > > >
> > > >  {
> > > >
> > > >       unsigned long target;
> > > >
> > > > @@ -403,7 +404,7 @@ static void __init test_trampoline(void)
> > > >
> > > >  static void __init test_branch_iform(void)
> > > >  {
> > > >
> > > > -     unsigned int instr;
> > > > +     ppc_inst instr;
> > > >
> > > >       unsigned long addr;
> > > >
> > > >       addr = (unsigned long)&instr;
> > > >
> > > > @@ -478,11 +479,11 @@ static void __init test_branch_iform(void)
> > > >
> > > >  static void __init test_create_function_call(void)
> > > >  {
> > > >
> > > > -     unsigned int *iptr;
> > > > +     ppc_inst *iptr;
> > > >
> > > >       unsigned long dest;
> > > >
> > > >       /* Check we can create a function call */
> > > >
> > > > -     iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> > > > +     iptr = (ppc_inst *)ppc_function_entry(test_trampoline);
> > > >
> > > >       dest = ppc_function_entry(test_create_function_call);
> > > >       patch_instruction(iptr, create_branch(iptr, dest,
> > > >       BRANCH_SET_LINK));
> > > >       check(instr_is_branch_to_addr(iptr, dest));
> > > >
> > > > @@ -491,7 +492,8 @@ static void __init test_create_function_call(void)
> > > >
> > > >  static void __init test_branch_bform(void)
> > > >  {
> > > >
> > > >       unsigned long addr;
> > > >
> > > > -     unsigned int *iptr, instr, flags;
> > > > +     ppc_inst *iptr, instr;
> > > > +     unsigned int flags;
> > > >
> > > >       iptr = &instr;
> > > >       addr = (unsigned long)iptr;
> > > >
> > > > @@ -561,7 +563,7 @@ static void __init test_branch_bform(void)
> > > >
> > > >  static void __init test_translate_branch(void)
> > > >  {
> > > >
> > > >       unsigned long addr;
> > > >
> > > > -     unsigned int *p, *q;
> > > > +     ppc_inst *p, *q;
> > > >
> > > >       void *buf;
> > > >
> > > >       buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> > > >
> > > > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > > > index c077acb983a1..1d9c766a89fe 100644
> > > > --- a/arch/powerpc/lib/sstep.c
> > > > +++ b/arch/powerpc/lib/sstep.c
> > > > @@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1,
> > > > long
> > > > v2)
> > > >
> > > >   * otherwise.
> > > >   */
> > > >
> > > >  int analyse_instr(struct instruction_op *op, const struct pt_regs
> > > >  *regs,
> > > >
> > > > -               unsigned int instr)
> > > > +               ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       unsigned int opcode, ra, rb, rc, rd, spr, u;
> > > >       unsigned long int imm;
> > > >
> > > > @@ -3101,7 +3101,7 @@ NOKPROBE_SYMBOL(emulate_loadstore);
> > > >
> > > >   * or -1 if the instruction is one that should not be stepped,
> > > >   * such as an rfid, or a mtmsrd that would clear MSR_RI.
> > > >   */
> > > >
> > > > -int emulate_step(struct pt_regs *regs, unsigned int instr)
> > > > +int emulate_step(struct pt_regs *regs, ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       struct instruction_op op;
> > > >       int r, err, type;
> > > >
> > > > diff --git a/arch/powerpc/lib/test_emulate_step.c
> > > > b/arch/powerpc/lib/test_emulate_step.c
> > > > index 42347067739c..158efc8a0f53 100644
> > > > --- a/arch/powerpc/lib/test_emulate_step.c
> > > > +++ b/arch/powerpc/lib/test_emulate_step.c
> > > > @@ -460,7 +460,7 @@ struct compute_test {
> > > >
> > > >       struct {
> > > >
> > > >               char *descr;
> > > >               unsigned long flags;
> > > >
> > > > -             unsigned int instr;
> > > > +             ppc_inst instr;
> > > >
> > > >               struct pt_regs regs;
> > > >
> > > >       } subtests[MAX_SUBTESTS + 1];
> > > >
> > > >  };
> > > >
> > > > @@ -841,7 +841,7 @@ static struct compute_test compute_tests[] = {
> > > >
> > > >  };
> > > >
> > > >  static int __init emulate_compute_instr(struct pt_regs *regs,
> > > >
> > > > -                                     unsigned int instr)
> > > > +                                     ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       struct instruction_op op;
> > > >
> > > > @@ -859,7 +859,7 @@ static int __init emulate_compute_instr(struct
> > > > pt_regs
> > > > *regs,
> > > >
> > > >  }
> > > >
> > > >  static int __init execute_compute_instr(struct pt_regs *regs,
> > > >
> > > > -                                     unsigned int instr)
> > > > +                                     ppc_inst instr)
> > > >
> > > >  {
> > > >
> > > >       extern int exec_instr(struct pt_regs *regs);
> > > >       extern s32 patch__exec_instr;
> > > >
> > > > @@ -890,7 +890,8 @@ static void __init run_tests_compute(void)
> > > >
> > > >       unsigned long flags;
> > > >       struct compute_test *test;
> > > >       struct pt_regs *regs, exp, got;
> > > >
> > > > -     unsigned int i, j, k, instr;
> > > > +     unsigned int i, j, k;
> > > > +     ppc_inst instr;
> > > >
> > > >       bool ignore_gpr, ignore_xer, ignore_ccr, passed;
> > > >
> > > >       for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
> > > >
> > > > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > > > index 7875d1a37770..a0bc442f9557 100644
> > > > --- a/arch/powerpc/xmon/xmon.c
> > > > +++ b/arch/powerpc/xmon/xmon.c
> > > > @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
> > > >
> > > >  static void insert_bpts(void)
> > > >  {
> > > >
> > > >       int i;
> > > >
> > > > -     unsigned int instr;
> > > > +     ppc_inst instr;
> > > >
> > > >       struct bpt *bp;
> > > >
> > > >       bp = bpts;
> > > >
> > > > @@ -914,7 +914,7 @@ static void insert_bpts(void)
> > > >
> > > >               patch_instruction(bp->instr, instr);
> > > >               if (bp->enabled & BP_CIABR)
> > > >
> > > >                       continue;
> > > >
> > > > -             if (patch_instruction((unsigned int *)bp->address,
> > > > +             if (patch_instruction((ppc_inst *)bp->address,
> > > >
> > > >                                                       bpinstr) != 0) {
> > > >
> > > >                       printf("Couldn't write instruction at %lx, "
> > > >
> > > >                              "disabling breakpoint there\n",
> > > >                              bp->address);
> > > >
> > > > @@ -943,7 +943,7 @@ static void remove_bpts(void)
> > > >
> > > >  {
> > > >
> > > >       int i;
> > > >       struct bpt *bp;
> > > >
> > > > -     unsigned instr;
> > > > +     ppc_inst instr;
> > > >
> > > >       bp = bpts;
> > > >       for (i = 0; i < NBPTS; ++i, ++bp) {
> > > >
> > > > @@ -952,7 +952,7 @@ static void remove_bpts(void)
> > > >
> > > >               if (mread(bp->address, &instr, 4) == 4
> > > >
> > > >                   && instr == bpinstr
> > > >                   && patch_instruction(
> > > >
> > > > -                     (unsigned int *)bp->address, bp->instr[0]) != 0)
> > > > +                     (ppc_inst *)bp->address, bp->instr[0]) != 0)
> > > >
> > > >                       printf("Couldn't remove breakpoint at %lx\n",
> > > >
> > > >                              bp->address);
> > > >
> > > >       }
> > > >
> > > > @@ -1159,7 +1159,7 @@ static int do_step(struct pt_regs *regs)
> > > >
> > > >   */
> > > >
> > > >  static int do_step(struct pt_regs *regs)
> > > >  {
> > > >
> > > > -     unsigned int instr;
> > > > +     ppc_inst instr;
> > > >
> > > >       int stepped;
> > > >
> > > >       force_enable_xmon();
> > > >
> > > > @@ -1325,7 +1325,7 @@ csum(void)
> > > >
> > > >   */
> > > >
> > > >  static long check_bp_loc(unsigned long addr)
> > > >  {
> > > >
> > > > -     unsigned int instr;
> > > > +     ppc_inst instr;
> > > >
> > > >       addr &= ~3;
> > > >       if (!is_kernel_addr(addr)) {
>
>
>
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2020-04-03  0:11 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-20  5:17 [PATCH v4 00/16] Initial Prefixed Instruction support Jordan Niethe
2020-03-20  5:17 ` [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
2020-03-23  6:19   ` Nicholas Piggin
2020-03-20  5:17 ` [PATCH v4 02/16] xmon: Move out-of-line instructions to text section Jordan Niethe
2020-03-23  5:59   ` Balamuruhan S
2020-03-23  6:05   ` Balamuruhan S
2020-03-23  9:26     ` Jordan Niethe
2020-03-23  6:22   ` Nicholas Piggin
2020-03-20  5:17 ` [PATCH v4 03/16] powerpc: Use a datatype for instructions Jordan Niethe
2020-03-23  6:07   ` Balamuruhan S
2020-03-23  6:23   ` Nicholas Piggin
2020-03-23  9:28     ` Jordan Niethe
2020-03-23  9:51       ` Nicholas Piggin
2020-03-24  2:58         ` Michael Ellerman
2020-03-24  3:21           ` Jordan Niethe
2020-04-01 10:32   ` Balamuruhan S
2020-04-01 23:52     ` Jordan Niethe
2020-04-02 23:44       ` Alistair Popple
2020-04-03  0:09         ` Jordan Niethe
2020-03-20  5:17 ` [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
2020-03-23  6:26   ` Nicholas Piggin
2020-03-23  9:29     ` Jordan Niethe
2020-03-20  5:17 ` [PATCH v4 05/16] powerpc: Use a function for masking instructions Jordan Niethe
2020-03-23  6:37   ` Nicholas Piggin
2020-03-23  9:31     ` Jordan Niethe
2020-03-20  5:17 ` [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code Jordan Niethe
2020-03-23  6:54   ` Balamuruhan S
2020-03-23  9:35     ` Jordan Niethe
2020-03-20  5:18 ` [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality Jordan Niethe
2020-03-23  6:43   ` Nicholas Piggin
2020-03-23  9:31     ` Jordan Niethe
2020-03-20  5:18 ` [PATCH v4 08/16] powerpc: Use an accessor for word instructions Jordan Niethe
2020-03-23 11:12   ` Balamuruhan S
2020-03-24  3:18     ` Jordan Niethe
2020-03-24  6:22       ` Balamuruhan S
2020-03-20  5:18 ` [PATCH v4 09/16] powerpc: Use a function for reading instructions Jordan Niethe
2020-03-23  8:00   ` Nicholas Piggin
2020-03-23  8:43     ` Balamuruhan S
2020-03-23 10:09     ` Jordan Niethe
2020-03-23 10:36       ` Nicholas Piggin
2020-03-20  5:18 ` [PATCH v4 10/16] powerpc: Make test_translate_branch() independent of instruction length Jordan Niethe
2020-03-20  5:18 ` [PATCH v4 11/16] powerpc: Enable Prefixed Instructions Jordan Niethe
2020-03-23  7:02   ` Nicholas Piggin
2020-03-20  5:18 ` [PATCH v4 12/16] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
2020-03-23  7:03   ` Nicholas Piggin
2020-03-20  5:18 ` [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
2020-03-23  7:05   ` Nicholas Piggin
2020-03-23  9:35     ` Jordan Niethe
2020-03-20  5:18 ` [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
2020-03-23  6:58   ` Nicholas Piggin
2020-03-23  7:33   ` Nicholas Piggin
2020-03-23 23:45     ` Jordan Niethe
2020-03-24  5:40       ` Nicholas Piggin
2020-03-30  9:05   ` Alistair Popple
2020-03-30  9:13     ` Jordan Niethe
2020-03-20  5:18 ` [PATCH v4 15/16] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
2020-03-23  8:54   ` Balamuruhan S
2020-03-20  5:18 ` [PATCH v4 16/16] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
2020-03-23 10:05   ` Balamuruhan S
2020-03-23  6:18 ` [PATCH v4 00/16] Initial Prefixed Instruction support Nicholas Piggin
2020-03-23  9:25   ` Jordan Niethe
2020-03-23 10:17     ` Nicholas Piggin
2020-03-24  2:54       ` Jordan Niethe
2020-03-24  2:59         ` Jordan Niethe
2020-03-24  5:44         ` Nicholas Piggin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).