All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/21] Initial Prefixed Instruction support
@ 2020-04-06  8:09 Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 01/21] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
                   ` (21 more replies)
  0 siblings, 22 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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.

v5 is based on feedback from Nick Piggins, Michael Ellerman, Balamuruhan
Suriyakumar and Alistair Popple.
The major changes:
    - The ppc instruction type is now a struct
    - Series now just based on next
    - ppc_inst_masked() dropped
    - Space for xmon breakpoints allocated in an assembly file
    - "Add prefixed instructions to instruction data type" patch seperated in
      to smaller patches
    - Calling convention for create_branch() is changed
    - Some places which had not been updated to use the data type are now updated

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 (20):
  powerpc/xmon: Remove store_inst() for patch_instruction()
  powerpc/xmon: Move out-of-line instructions to text section
  powerpc: Change calling convention for create_branch() et. al.
  powerpc: Use a macro for creating instructions from u32s
  powerpc: Use a function for getting the instruction op code
  powerpc: Use an accessor for instructions
  powerpc: Use a function for byte swapping instructions
  powerpc: Introduce functions for instruction equality
  powerpc: Use a datatype for instructions
  powerpc: Use a function for reading instructions
  powerpc: Define and use __get_user_instr{,inatomic}()
  powerpc: Introduce a function for reporting instruction length
  powerpc/xmon: Use a function for reading instructions
  powerpc/xmon: Move insertion of breakpoint for xol'ing
  powerpc: Make test_translate_branch() independent of instruction
    length
  powerpc: Define new SRR1 bits for a future ISA version
  powerpc64: Add prefixed instructions to instruction data type
  powerpc: Support prefixed instructions in alignment handler
  powerpc sstep: Add support for prefixed load/stores
  powerpc sstep: Add support for prefixed fixed-point arithmetic

 arch/powerpc/include/asm/code-patching.h |  37 +-
 arch/powerpc/include/asm/inst.h          | 106 ++++++
 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       |  28 ++
 arch/powerpc/include/asm/uprobes.h       |   7 +-
 arch/powerpc/kernel/align.c              |  13 +-
 arch/powerpc/kernel/epapr_paravirt.c     |   5 +-
 arch/powerpc/kernel/hw_breakpoint.c      |   5 +-
 arch/powerpc/kernel/jump_label.c         |   5 +-
 arch/powerpc/kernel/kgdb.c               |   9 +-
 arch/powerpc/kernel/kprobes.c            |  24 +-
 arch/powerpc/kernel/mce_power.c          |   5 +-
 arch/powerpc/kernel/module_64.c          |   3 +-
 arch/powerpc/kernel/optprobes.c          |  91 +++--
 arch/powerpc/kernel/optprobes_head.S     |   3 +
 arch/powerpc/kernel/security.c           |   9 +-
 arch/powerpc/kernel/setup_32.c           |   4 +-
 arch/powerpc/kernel/trace/ftrace.c       | 190 ++++++----
 arch/powerpc/kernel/traps.c              |  20 +-
 arch/powerpc/kernel/uprobes.c            |   3 +-
 arch/powerpc/kernel/vecemu.c             |  20 +-
 arch/powerpc/kvm/book3s_hv_nested.c      |   2 +-
 arch/powerpc/kvm/book3s_hv_rm_mmu.c      |   2 +-
 arch/powerpc/kvm/emulate_loadstore.c     |   2 +-
 arch/powerpc/lib/code-patching.c         | 289 +++++++-------
 arch/powerpc/lib/feature-fixups.c        |  69 ++--
 arch/powerpc/lib/sstep.c                 | 455 ++++++++++++++++-------
 arch/powerpc/lib/test_emulate_step.c     |  56 +--
 arch/powerpc/perf/core-book3s.c          |   4 +-
 arch/powerpc/xmon/Makefile               |   2 +-
 arch/powerpc/xmon/xmon.c                 |  94 +++--
 arch/powerpc/xmon/xmon_bpts.S            |  10 +
 arch/powerpc/xmon/xmon_bpts.h            |   8 +
 35 files changed, 1042 insertions(+), 562 deletions(-)
 create mode 100644 arch/powerpc/include/asm/inst.h
 create mode 100644 arch/powerpc/xmon/xmon_bpts.S
 create mode 100644 arch/powerpc/xmon/xmon_bpts.h

-- 
2.17.1


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

* [PATCH v5 01/21] powerpc/xmon: Remove store_inst() for patch_instruction()
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section Jordan Niethe
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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().

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 related	[flat|nested] 71+ messages in thread

* [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 01/21] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07  6:45   ` Balamuruhan S
  2020-04-09  6:11   ` Christophe Leroy
  2020-04-06  8:09 ` [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al Jordan Niethe
                   ` (19 subsequent siblings)
  21 siblings, 2 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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
v5: - Do not use __section(), use a .space directive in .S file
    - Simplify in_breakpoint_table() calculation
    - Define BPT_SIZE
---
 arch/powerpc/xmon/Makefile    |  2 +-
 arch/powerpc/xmon/xmon.c      | 23 +++++++++++++----------
 arch/powerpc/xmon/xmon_bpts.S |  8 ++++++++
 arch/powerpc/xmon/xmon_bpts.h |  8 ++++++++
 4 files changed, 30 insertions(+), 11 deletions(-)
 create mode 100644 arch/powerpc/xmon/xmon_bpts.S
 create mode 100644 arch/powerpc/xmon/xmon_bpts.h

diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index c3842dbeb1b7..515a13ea6f28 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -21,7 +21,7 @@ endif
 
 ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
 
-obj-y			+= xmon.o nonstdio.o spr_access.o
+obj-y			+= xmon.o nonstdio.o spr_access.o xmon_bpts.o
 
 ifdef CONFIG_XMON_DISASSEMBLY
 obj-y			+= ppc-dis.o ppc-opc.o
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 02e3bd62cab4..049375206510 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -62,6 +62,7 @@
 
 #include "nonstdio.h"
 #include "dis-asm.h"
+#include "xmon_bpts.h"
 
 #ifdef CONFIG_SMP
 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
@@ -97,7 +98,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;
@@ -108,7 +109,6 @@ struct bpt {
 #define BP_TRAP		2
 #define BP_DABR		4
 
-#define NBPTS	256
 static struct bpt bpts[NBPTS];
 static struct bpt dabr;
 static struct bpt *iabr;
@@ -116,6 +116,10 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
 
 #define BP_NUM(bp)	((bp) - bpts + 1)
 
+#define BPT_SIZE	(sizeof(unsigned int) * 2)
+#define BPT_WORDS	(BPT_SIZE / sizeof(unsigned int))
+extern unsigned int bpt_table[NBPTS * BPT_WORDS];
+
 /* Prototypes */
 static int cmds(struct pt_regs *);
 static int mread(unsigned long, void *, int);
@@ -853,15 +857,13 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
 {
 	unsigned long 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]))
+	*offp = off % BPT_SIZE;
+	if (*offp != 0 && *offp != 4)
 		return NULL;
-	*offp = off - offsetof(struct bpt, instr[0]);
-	return (struct bpt *) (nip - off);
+	return bpts + (off / BPT_SIZE);
 }
 
 static struct bpt *new_breakpoint(unsigned long a)
@@ -876,7 +878,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;
 		}
 	}
diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
new file mode 100644
index 000000000000..ebb2dbc70ca8
--- /dev/null
+++ b/arch/powerpc/xmon/xmon_bpts.S
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/ppc_asm.h>
+#include <asm/asm-compat.h>
+#include "xmon_bpts.h"
+
+.global bpt_table
+bpt_table:
+	.space NBPTS * 8
diff --git a/arch/powerpc/xmon/xmon_bpts.h b/arch/powerpc/xmon/xmon_bpts.h
new file mode 100644
index 000000000000..840e70be7945
--- /dev/null
+++ b/arch/powerpc/xmon/xmon_bpts.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef XMON_BPTS_H
+#define XMON_BPTS_H
+
+#define NBPTS	256
+
+#endif /* XMON_BPTS_H */
+
-- 
2.17.1


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

* [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al.
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 01/21] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06 10:25     ` kbuild test robot
  2020-04-07  6:10   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 04/21] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
                   ` (18 subsequent siblings)
  21 siblings, 2 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

create_branch(), create_cond_branch() and translate_branch() return the
instruction that they create, or return 0 to signal an error. Seperate
these concerns in preparation for an instruction type that is not just
an unsigned int.  Fill the created instruction to a pointer passed as
the first parameter to the function and use a non-zero return value to
signify an error.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v5: New to series
---
 arch/powerpc/include/asm/code-patching.h |  12 +-
 arch/powerpc/kernel/optprobes.c          |  24 ++--
 arch/powerpc/kernel/setup_32.c           |   2 +-
 arch/powerpc/kernel/trace/ftrace.c       |  24 ++--
 arch/powerpc/lib/code-patching.c         | 133 +++++++++++++----------
 arch/powerpc/lib/feature-fixups.c        |   5 +-
 6 files changed, 117 insertions(+), 83 deletions(-)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 898b54262881..351dda7215b6 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -22,10 +22,10 @@
 #define BRANCH_ABSOLUTE	0x2
 
 bool is_offset_in_branch_range(long offset);
-unsigned int create_branch(const unsigned int *addr,
-			   unsigned long target, int flags);
-unsigned int create_cond_branch(const unsigned int *addr,
-				unsigned long target, int flags);
+int create_branch(unsigned int *instr, const unsigned int *addr,
+		  unsigned long target, int flags);
+int create_cond_branch(unsigned int *instr, const unsigned int *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);
@@ -60,8 +60,8 @@ 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);
+int translate_branch(unsigned int *instr, const unsigned int *dest,
+		     const unsigned int *src);
 extern bool is_conditional_branch(unsigned int instr);
 #ifdef CONFIG_PPC_BOOK3E_64
 void __patch_exception(int exc, unsigned long addr);
diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index 024f7aad1952..445b3dad82dc 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -251,15 +251,17 @@ 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,
-				(unsigned long)op_callback_addr,
-				BRANCH_SET_LINK);
+	rc = create_branch(&branch_op_callback,
+			   (unsigned int *)buff + TMPL_CALL_HDLR_IDX,
+			   (unsigned long)op_callback_addr,
+			   BRANCH_SET_LINK);
 
-	branch_emulate_step = create_branch((unsigned int *)buff + TMPL_EMULATE_IDX,
-				(unsigned long)emulate_step_addr,
-				BRANCH_SET_LINK);
+	rc |= create_branch(&branch_emulate_step,
+			    (unsigned int *)buff + TMPL_EMULATE_IDX,
+			    (unsigned long)emulate_step_addr,
+			    BRANCH_SET_LINK);
 
-	if (!branch_op_callback || !branch_emulate_step)
+	if (rc)
 		goto error;
 
 	patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
@@ -305,6 +307,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe *op)
 
 void arch_optimize_kprobes(struct list_head *oplist)
 {
+	unsigned int instr;
 	struct optimized_kprobe *op;
 	struct optimized_kprobe *tmp;
 
@@ -315,9 +318,10 @@ 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,
-				      (unsigned long)op->optinsn.insn, 0));
+		create_branch(&instr,
+			      (unsigned int *)op->kp.addr,
+			      (unsigned long)op->optinsn.insn, 0);
+		patch_instruction(op->kp.addr, instr);
 		list_del_init(&op->list);
 	}
 }
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 5b49b26eb154..c1bdd462c5c0 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -88,7 +88,7 @@ notrace void __init machine_init(u64 dt_ptr)
 
 	patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
 
-	insn = create_cond_branch(addr, branch_target(addr), 0x820000);
+	create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
 	patch_instruction(addr, insn);	/* replace b by bne cr0 */
 
 	/* Do some early initialization based on the flat device tree */
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 7ea0ca044b65..4dcb379133f8 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -48,7 +48,7 @@ ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 	addr = ppc_function_entry((void *)addr);
 
 	/* if (link) set op to 'bl' else 'b' */
-	op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
+	create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
 
 	return op;
 }
@@ -89,10 +89,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
  */
 static int test_24bit_addr(unsigned long ip, unsigned long addr)
 {
+	unsigned int op;
 	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(&op, (unsigned int *)ip, addr, 0) == 0;
 }
 
 static int is_bl_op(unsigned int op)
@@ -287,6 +288,7 @@ __ftrace_make_nop(struct module *mod,
 static unsigned long find_ftrace_tramp(unsigned long ip)
 {
 	int i;
+	unsigned int instr;
 
 	/*
 	 * We have the compiler generated long_branch tramps at the end
@@ -295,7 +297,8 @@ 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 (create_branch(&instr, (void *)ip,
+				  ftrace_tramps[i], 0) == 0)
 			return ftrace_tramps[i];
 
 	return 0;
@@ -324,6 +327,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
 {
 	int i, op;
 	unsigned long ptr;
+	unsigned int instr;
 	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
 
 	/* Is this a known long jump tramp? */
@@ -366,7 +370,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 (create_branch(&instr, (void *)tramp, ptr, 0)) {
 		pr_debug("%ps is not reachable from existing mcount tramp\n",
 				(void *)ptr);
 		return -1;
@@ -511,6 +515,7 @@ static int
 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
 	unsigned int op[2];
+	unsigned int instr;
 	void *ip = (void *)rec->ip;
 	unsigned long entry, ptr, tramp;
 	struct module *mod = rec->arch.mod;
@@ -557,7 +562,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 (create_branch(&instr, ip, tramp, BRANCH_SET_LINK)) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
@@ -574,6 +579,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 static int
 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
+	int err;
 	unsigned int op;
 	unsigned long ip = rec->ip;
 
@@ -594,9 +600,9 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	/* create the branch to the trampoline */
-	op = create_branch((unsigned int *)ip,
-			   rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
-	if (!op) {
+	err = create_branch(&op, (unsigned int *)ip,
+			    rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
+	if (!err) {
 		pr_err("REL24 out of range!\n");
 		return -EINVAL;
 	}
@@ -776,7 +782,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(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 3345f039a876..4af564aeedf1 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -196,7 +196,10 @@ NOKPROBE_SYMBOL(patch_instruction);
 
 int patch_branch(unsigned int *addr, unsigned long target, int flags)
 {
-	return patch_instruction(addr, create_branch(addr, target, flags));
+	unsigned int instr;
+
+	create_branch(&instr, addr, target, flags);
+	return patch_instruction(addr, instr);
 }
 
 bool is_offset_in_branch_range(long offset)
@@ -243,30 +246,30 @@ bool is_conditional_branch(unsigned int instr)
 }
 NOKPROBE_SYMBOL(is_conditional_branch);
 
-unsigned int create_branch(const unsigned int *addr,
-			   unsigned long target, int flags)
+int create_branch(unsigned int *instr,
+		  const unsigned int *addr,
+		  unsigned long target, int flags)
 {
-	unsigned int instruction;
 	long offset;
 
+	*instr = 0;
 	offset = target;
 	if (! (flags & BRANCH_ABSOLUTE))
 		offset = offset - (unsigned long)addr;
 
 	/* Check we can represent the target in the instruction format */
 	if (!is_offset_in_branch_range(offset))
-		return 0;
+		return 1;
 
 	/* Mask out the flags and target, so they don't step on each other. */
-	instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
+	*instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
 
-	return instruction;
+	return 0;
 }
 
-unsigned int create_cond_branch(const unsigned int *addr,
-				unsigned long target, int flags)
+int create_cond_branch(unsigned int *instr, const unsigned int *addr,
+		       unsigned long target, int flags)
 {
-	unsigned int instruction;
 	long offset;
 
 	offset = target;
@@ -275,12 +278,12 @@ 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 1;
 
 	/* Mask out the flags and target, so they don't step on each other. */
-	instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
+	*instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
 
-	return instruction;
+	return 0;
 }
 
 static unsigned int branch_opcode(unsigned int instr)
@@ -361,18 +364,18 @@ 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)
+int translate_branch(unsigned int *instr, const unsigned int *dest, const unsigned int *src)
 {
 	unsigned long target;
 
 	target = branch_target(src);
 
 	if (instr_is_branch_iform(*src))
-		return create_branch(dest, target, *src);
+		return create_branch(instr, dest, target, *src);
 	else if (instr_is_branch_bform(*src))
-		return create_cond_branch(dest, target, *src);
+		return create_cond_branch(instr, dest, target, *src);
 
-	return 0;
+	return 1;
 }
 
 #ifdef CONFIG_PPC_BOOK3E_64
@@ -403,6 +406,7 @@ static void __init test_trampoline(void)
 
 static void __init test_branch_iform(void)
 {
+	int err;
 	unsigned int instr;
 	unsigned long addr;
 
@@ -443,35 +447,35 @@ static void __init test_branch_iform(void)
 	check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
 
 	/* Branch to self, with link */
-	instr = create_branch(&instr, addr, BRANCH_SET_LINK);
+	err = create_branch(&instr, &instr, addr, BRANCH_SET_LINK);
 	check(instr_is_branch_to_addr(&instr, addr));
 
 	/* Branch to self - 0x100, with link */
-	instr = create_branch(&instr, addr - 0x100, BRANCH_SET_LINK);
+	err = create_branch(&instr, &instr, addr - 0x100, BRANCH_SET_LINK);
 	check(instr_is_branch_to_addr(&instr, addr - 0x100));
 
 	/* Branch to self + 0x100, no link */
-	instr = create_branch(&instr, addr + 0x100, 0);
+	err = create_branch(&instr, &instr, addr + 0x100, 0);
 	check(instr_is_branch_to_addr(&instr, addr + 0x100));
 
 	/* Maximum relative negative offset, - 32 MB */
-	instr = create_branch(&instr, addr - 0x2000000, BRANCH_SET_LINK);
+	err = create_branch(&instr, &instr, addr - 0x2000000, BRANCH_SET_LINK);
 	check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
 
 	/* Out of range relative negative offset, - 32 MB + 4*/
-	instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK);
-	check(instr == 0);
+	err = create_branch(&instr, &instr, addr - 0x2000004, BRANCH_SET_LINK);
+	check(err);
 
 	/* Out of range relative positive offset, + 32 MB */
-	instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK);
-	check(instr == 0);
+	err = create_branch(&instr, &instr, addr + 0x2000000, BRANCH_SET_LINK);
+	check(err);
 
 	/* Unaligned target */
-	instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK);
-	check(instr == 0);
+	err = create_branch(&instr, &instr, addr + 3, BRANCH_SET_LINK);
+	check(err);
 
 	/* Check flags are masked correctly */
-	instr = create_branch(&instr, addr, 0xFFFFFFFC);
+	err = create_branch(&instr, &instr, addr, 0xFFFFFFFC);
 	check(instr_is_branch_to_addr(&instr, addr));
 	check(instr == 0x48000000);
 }
@@ -480,16 +484,19 @@ static void __init test_create_function_call(void)
 {
 	unsigned int *iptr;
 	unsigned long dest;
+	unsigned int instr;
 
 	/* Check we can create a function call */
 	iptr = (unsigned int *)ppc_function_entry(test_trampoline);
 	dest = ppc_function_entry(test_create_function_call);
-	patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
+	create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
+	patch_instruction(iptr, instr);
 	check(instr_is_branch_to_addr(iptr, dest));
 }
 
 static void __init test_branch_bform(void)
 {
+	int err;
 	unsigned long addr;
 	unsigned int *iptr, instr, flags;
 
@@ -525,35 +532,35 @@ static void __init test_branch_bform(void)
 	flags = 0x3ff000 | BRANCH_SET_LINK;
 
 	/* Branch to self */
-	instr = create_cond_branch(iptr, addr, flags);
+	err = create_cond_branch(&instr, iptr, addr, flags);
 	check(instr_is_branch_to_addr(&instr, addr));
 
 	/* Branch to self - 0x100 */
-	instr = create_cond_branch(iptr, addr - 0x100, flags);
+	err = create_cond_branch(&instr, iptr, addr - 0x100, flags);
 	check(instr_is_branch_to_addr(&instr, addr - 0x100));
 
 	/* Branch to self + 0x100 */
-	instr = create_cond_branch(iptr, addr + 0x100, flags);
+	err = create_cond_branch(&instr, iptr, addr + 0x100, flags);
 	check(instr_is_branch_to_addr(&instr, addr + 0x100));
 
 	/* Maximum relative negative offset, - 32 KB */
-	instr = create_cond_branch(iptr, addr - 0x8000, flags);
+	err = create_cond_branch(&instr, iptr, addr - 0x8000, flags);
 	check(instr_is_branch_to_addr(&instr, addr - 0x8000));
 
 	/* Out of range relative negative offset, - 32 KB + 4*/
-	instr = create_cond_branch(iptr, addr - 0x8004, flags);
-	check(instr == 0);
+	err = create_cond_branch(&instr, iptr, addr - 0x8004, flags);
+	check(err);
 
 	/* Out of range relative positive offset, + 32 KB */
-	instr = create_cond_branch(iptr, addr + 0x8000, flags);
-	check(instr == 0);
+	err = create_cond_branch(&instr, iptr, addr + 0x8000, flags);
+	check(err);
 
 	/* Unaligned target */
-	instr = create_cond_branch(iptr, addr + 3, flags);
-	check(instr == 0);
+	err = create_cond_branch(&instr, iptr, addr + 3, flags);
+	check(err);
 
 	/* Check flags are masked correctly */
-	instr = create_cond_branch(iptr, addr, 0xFFFFFFFC);
+	err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
 	check(instr_is_branch_to_addr(&instr, addr));
 	check(instr == 0x43FF0000);
 }
@@ -562,6 +569,7 @@ static void __init test_translate_branch(void)
 {
 	unsigned long addr;
 	unsigned int *p, *q;
+	unsigned int instr;
 	void *buf;
 
 	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
@@ -575,7 +583,8 @@ static void __init test_translate_branch(void)
 	patch_branch(p, addr, 0);
 	check(instr_is_branch_to_addr(p, addr));
 	q = p + 1;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(q, addr));
 
 	/* Maximum negative case, move b . to addr + 32 MB */
@@ -583,7 +592,8 @@ static void __init test_translate_branch(void)
 	addr = (unsigned long)p;
 	patch_branch(p, addr, 0);
 	q = buf + 0x2000000;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 	check(*q == 0x4a000000);
@@ -593,7 +603,8 @@ static void __init test_translate_branch(void)
 	addr = (unsigned long)p;
 	patch_branch(p, addr, 0);
 	q = buf + 4;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 	check(*q == 0x49fffffc);
@@ -603,7 +614,8 @@ static void __init test_translate_branch(void)
 	addr = 0x1000000 + (unsigned long)buf;
 	patch_branch(p, addr, BRANCH_SET_LINK);
 	q = buf + 0x1400000;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 
@@ -612,7 +624,8 @@ static void __init test_translate_branch(void)
 	addr = 0x2000000 + (unsigned long)buf;
 	patch_branch(p, addr, 0);
 	q = buf + 4;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 
@@ -622,18 +635,22 @@ static void __init test_translate_branch(void)
 	/* Simple case, branch to self moved a little */
 	p = buf;
 	addr = (unsigned long)p;
-	patch_instruction(p, create_cond_branch(p, addr, 0));
+	create_cond_branch(&instr, p, addr, 0);
+	patch_instruction(p, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	q = p + 1;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(q, addr));
 
 	/* Maximum negative case, move b . to addr + 32 KB */
 	p = buf;
 	addr = (unsigned long)p;
-	patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
+	create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
+	patch_instruction(p, instr);
 	q = buf + 0x8000;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 	check(*q == 0x43ff8000);
@@ -641,9 +658,11 @@ static void __init test_translate_branch(void)
 	/* Maximum positive case, move x to x - 32 KB + 4 */
 	p = buf + 0x8000;
 	addr = (unsigned long)p;
-	patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
+	create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
+	patch_instruction(p, instr);
 	q = buf + 4;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 	check(*q == 0x43ff7ffc);
@@ -651,18 +670,22 @@ static void __init test_translate_branch(void)
 	/* Jump to x + 12 KB moved to x + 20 KB */
 	p = buf;
 	addr = 0x3000 + (unsigned long)buf;
-	patch_instruction(p, create_cond_branch(p, addr, BRANCH_SET_LINK));
+	create_cond_branch(&instr, p, addr, BRANCH_SET_LINK);
+	patch_instruction(p, instr);
 	q = buf + 0x5000;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 
 	/* Jump to x + 8 KB moved to x - 8 KB + 4 */
 	p = buf + 0x2000;
 	addr = 0x4000 + (unsigned long)buf;
-	patch_instruction(p, create_cond_branch(p, addr, 0));
+	create_cond_branch(&instr, p, addr, 0);
+	patch_instruction(p, instr);
 	q = buf + 4;
-	patch_instruction(q, translate_branch(q, p));
+	translate_branch(&instr, q, p);
+	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
 
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 4ba634b89ce5..b129d7b4e7dd 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -44,6 +44,7 @@ static unsigned int *calc_addr(struct fixup_entry *fcur, long offset)
 static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
 				 unsigned int *alt_start, unsigned int *alt_end)
 {
+	int err;
 	unsigned int instr;
 
 	instr = *src;
@@ -53,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 (!instr)
+			err = translate_branch(&instr, dest, src);
+			if (err)
 				return 1;
 		}
 	}
-- 
2.17.1


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

* [PATCH v5 04/21] powerpc: Use a macro for creating instructions from u32s
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (2 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07  6:40   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code Jordan Niethe
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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.  A
macro is used so that instructions can be used as initializer elements.
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
v5: - Rename PPC_INST() -> ppc_inst().
    - Use on epapr_paravirt.c, kgdb.c
---
 arch/powerpc/include/asm/code-patching.h |  3 +-
 arch/powerpc/include/asm/inst.h          | 11 +++++
 arch/powerpc/kernel/align.c              |  1 +
 arch/powerpc/kernel/epapr_paravirt.c     |  5 ++-
 arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
 arch/powerpc/kernel/jump_label.c         |  3 +-
 arch/powerpc/kernel/kgdb.c               |  5 ++-
 arch/powerpc/kernel/kprobes.c            |  5 ++-
 arch/powerpc/kernel/module_64.c          |  3 +-
 arch/powerpc/kernel/optprobes.c          | 31 ++++++-------
 arch/powerpc/kernel/security.c           |  9 ++--
 arch/powerpc/kernel/trace/ftrace.c       | 25 ++++++-----
 arch/powerpc/kernel/uprobes.c            |  1 +
 arch/powerpc/kvm/emulate_loadstore.c     |  2 +-
 arch/powerpc/lib/code-patching.c         | 57 ++++++++++++------------
 arch/powerpc/lib/feature-fixups.c        | 39 ++++++++--------
 arch/powerpc/lib/test_emulate_step.c     | 39 ++++++++--------
 arch/powerpc/xmon/xmon.c                 |  7 +--
 18 files changed, 138 insertions(+), 111 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 351dda7215b6..48e021957ee5 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);
@@ -48,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/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
new file mode 100644
index 000000000000..5298ba33b6e5
--- /dev/null
+++ b/arch/powerpc/include/asm/inst.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _ASM_INST_H
+#define _ASM_INST_H
+
+/*
+ * Instruction data type for POWER
+ */
+
+#define ppc_inst(x) (x)
+
+#endif /* _ASM_INST_H */
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 92045ed64976..86e9bf62f18c 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -24,6 +24,7 @@
 #include <asm/disassemble.h>
 #include <asm/cpu_has_feature.h>
 #include <asm/sstep.h>
+#include <asm/inst.h>
 
 struct aligninfo {
 	unsigned char len;
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c
index 9d32158ce36f..c53e863fb484 100644
--- a/arch/powerpc/kernel/epapr_paravirt.c
+++ b/arch/powerpc/kernel/epapr_paravirt.c
@@ -11,6 +11,7 @@
 #include <asm/cacheflush.h>
 #include <asm/code-patching.h>
 #include <asm/machdep.h>
+#include <asm/inst.h>
 
 #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
 extern void epapr_ev_idle(void);
@@ -37,9 +38,9 @@ static int __init early_init_dt_scan_epapr(unsigned long node,
 
 	for (i = 0; i < (len / 4); i++) {
 		u32 inst = be32_to_cpu(insts[i]);
-		patch_instruction(epapr_hypercall_start + i, inst);
+		patch_instruction(epapr_hypercall_start + i, ppc_inst(inst));
 #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
-		patch_instruction(epapr_ev_idle_start + i, inst);
+		patch_instruction(epapr_ev_idle_start + i, ppc_inst(inst));
 #endif
 	}
 
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 2462cd7c565c..79f51f182a83 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;
+	unsigned int 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..daa4afce7ec8 100644
--- a/arch/powerpc/kernel/jump_label.c
+++ b/arch/powerpc/kernel/jump_label.c
@@ -6,6 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/jump_label.h>
 #include <asm/code-patching.h>
+#include <asm/inst.h>
 
 void arch_jump_label_transform(struct jump_entry *entry,
 			       enum jump_label_type type)
@@ -15,5 +16,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/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 7dd55eb1259d..a6b38a19133f 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -26,6 +26,7 @@
 #include <asm/debug.h>
 #include <asm/code-patching.h>
 #include <linux/slab.h>
+#include <asm/inst.h>
 
 /*
  * This table contains the mapping between PowerPC hardware trap types, and
@@ -424,7 +425,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
 	if (err)
 		return err;
 
-	err = patch_instruction(addr, BREAK_INSTR);
+	err = patch_instruction(addr, ppc_inst(BREAK_INSTR));
 	if (err)
 		return -EFAULT;
 
@@ -439,7 +440,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
 	unsigned int instr = *(unsigned int *)bpt->saved_instr;
 	unsigned int *addr = (unsigned int *)bpt->bpt_addr;
 
-	err = patch_instruction(addr, instr);
+	err = patch_instruction(addr, ppc_inst(instr));
 	if (err)
 		return -EFAULT;
 
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 2d27ec4feee4..a1a3686f41c6 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -23,6 +23,7 @@
 #include <asm/cacheflush.h>
 #include <asm/sstep.h>
 #include <asm/sections.h>
+#include <asm/inst.h>
 #include <linux/uaccess.h>
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
@@ -138,13 +139,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..7fd6b29edcb2 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -20,6 +20,7 @@
 #include <linux/sort.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
+#include <asm/inst.h>
 
 /* FIXME: We don't do .init separately.  To do this, we'd need to have
    a separate r2 value in the init and core section, and stub between
@@ -506,7 +507,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 445b3dad82dc..3b33ebf18859 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -16,6 +16,7 @@
 #include <asm/code-patching.h>
 #include <asm/sstep.h>
 #include <asm/ppc-opcode.h>
+#include <asm/inst.h>
 
 #define TMPL_CALL_HDLR_IDX	\
 	(optprobe_template_call_handler - optprobe_template_entry)
@@ -147,13 +148,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 +164,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 +231,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..81a288b1a603 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -14,6 +14,7 @@
 #include <asm/debugfs.h>
 #include <asm/security_features.h>
 #include <asm/setup.h>
+#include <asm/inst.h>
 
 
 u64 powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
@@ -403,9 +404,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 +429,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 +440,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 4dcb379133f8..47233e671c18 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
@@ -161,7 +162,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 +170,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 +189,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 +200,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 +276,7 @@ __ftrace_make_nop(struct module *mod,
 		return -EINVAL;
 	}
 
-	op = PPC_INST_NOP;
+	op = ppc_inst(PPC_INST_NOP);
 
 	if (patch_instruction((unsigned int *)ip, op))
 		return -EPERM;
@@ -420,7 +421,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((unsigned int *)ip, ppc_inst(PPC_INST_NOP))) {
 		pr_err("Patching NOP failed.\n");
 		return -EPERM;
 	}
@@ -442,7 +443,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);
@@ -496,7 +497,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int 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 != ppc_inst(0x48000008)) || ((op1 & 0xffff0000) != 0xe8410000))
 		return 0;
 	return 1;
 }
@@ -505,7 +506,7 @@ static int
 expected_nop_sequence(void *ip, unsigned int op0, unsigned int 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;
 }
@@ -588,7 +589,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;
 	}
@@ -645,7 +646,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;
 	}
@@ -676,7 +677,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/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index 1cfef0e5fec5..31c870287f2b 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -14,6 +14,7 @@
 #include <linux/kdebug.h>
 
 #include <asm/sstep.h>
+#include <asm/inst.h>
 
 #define UPROBE_TRAP_NR	UINT_MAX
 
diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c
index 1139bc56e004..135d0e686622 100644
--- a/arch/powerpc/kvm/emulate_loadstore.c
+++ b/arch/powerpc/kvm/emulate_loadstore.c
@@ -95,7 +95,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 4af564aeedf1..fdf0d6ea3575 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -17,6 +17,7 @@
 #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)
@@ -413,37 +414,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 */
@@ -477,7 +478,7 @@ static void __init test_branch_iform(void)
 	/* Check flags are masked correctly */
 	err = create_branch(&instr, &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)
@@ -504,28 +505,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 */
@@ -562,7 +563,7 @@ static void __init test_branch_bform(void)
 	/* Check flags are masked correctly */
 	err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
 	check(instr_is_branch_to_addr(&instr, addr));
-	check(instr == 0x43FF0000);
+	check(instr == ppc_inst(0x43FF0000));
 }
 
 static void __init test_translate_branch(void)
@@ -596,7 +597,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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;
@@ -607,7 +608,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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;
@@ -653,7 +654,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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;
@@ -665,7 +666,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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 b129d7b4e7dd..6e7479b8887a 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;
@@ -89,7 +90,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;
 }
@@ -146,15 +147,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,
@@ -207,12 +208,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" :
@@ -260,9 +261,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,
@@ -295,7 +296,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);
@@ -338,8 +339,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);
@@ -353,7 +354,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));
 	}
 }
 
@@ -382,7 +383,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));
 	}
 }
 
@@ -400,7 +401,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 42347067739c..88b17226a493 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 049375206510..68ecb39dd9cc 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>
@@ -949,7 +950,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(
 			(unsigned int *)bp->address, bp->instr[0]) != 0)
 			printf("Couldn't remove breakpoint at %lx\n",
@@ -2845,7 +2846,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
 {
 	int nr, dotted;
 	unsigned long first_adr;
-	unsigned int inst, last_inst = 0;
+	unsigned int inst, last_inst = ppc_inst(0);
 	unsigned char val[4];
 
 	dotted = 0;
@@ -2858,7 +2859,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] 71+ messages in thread

* [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (3 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 04/21] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:22   ` Christophe Leroy
                     ` (2 more replies)
  2020-04-06  8:09 ` [PATCH v5 06/21] powerpc: Use an accessor for instructions Jordan Niethe
                   ` (16 subsequent siblings)
  21 siblings, 3 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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/include/asm/inst.h  | 5 +++++
 arch/powerpc/kernel/align.c      | 2 +-
 arch/powerpc/lib/code-patching.c | 4 ++--
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 5298ba33b6e5..93959016fe4b 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -8,4 +8,9 @@
 
 #define ppc_inst(x) (x)
 
+static inline int ppc_inst_opcode(u32 x)
+{
+	return x >> 26;
+}
+
 #endif /* _ASM_INST_H */
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 86e9bf62f18c..691013aa9f3c 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -314,7 +314,7 @@ int fix_alignment(struct pt_regs *regs)
 	}
 
 #ifdef CONFIG_SPE
-	if ((instr >> 26) == 0x4) {
+	if (ppc_inst_opcode(instr) == 0x4) {
 		int reg = (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 fdf0d6ea3575..099a515202aa 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -231,7 +231,7 @@ bool is_offset_in_branch_range(long offset)
  */
 bool is_conditional_branch(unsigned int instr)
 {
-	unsigned int opcode = instr >> 26;
+	unsigned int opcode = ppc_inst_opcode(instr);
 
 	if (opcode == 16)       /* bc, bca, bcl, bcla */
 		return true;
@@ -289,7 +289,7 @@ int create_cond_branch(unsigned int *instr, const unsigned int *addr,
 
 static unsigned int branch_opcode(unsigned int instr)
 {
-	return (instr >> 26) & 0x3F;
+	return ppc_inst_opcode(instr) & 0x3F;
 }
 
 static int instr_is_branch_iform(unsigned int instr)
-- 
2.17.1


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

* [PATCH v5 06/21] powerpc: Use an accessor for instructions
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (4 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 07/21] powerpc: Use a function for byte swapping instructions Jordan Niethe
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

In preparation for introducing a more complicated instruction type to
accomodate prefixed instructions use an accessor for getting an
instruction as a u32. Currently this does nothing.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v4: New to series
v5: Remove references to 'word' instructions
---
 arch/powerpc/include/asm/inst.h      |   5 +
 arch/powerpc/include/asm/sstep.h     |   6 +-
 arch/powerpc/kernel/align.c          |   4 +-
 arch/powerpc/kernel/kprobes.c        |   2 +-
 arch/powerpc/kernel/trace/ftrace.c   |  22 +--
 arch/powerpc/kernel/vecemu.c         |  17 +-
 arch/powerpc/lib/code-patching.c     |  18 +-
 arch/powerpc/lib/sstep.c             | 270 ++++++++++++++-------------
 arch/powerpc/lib/test_emulate_step.c |   6 +-
 arch/powerpc/xmon/xmon.c             |   4 +-
 10 files changed, 182 insertions(+), 172 deletions(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 93959016fe4b..15f570bef936 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -8,6 +8,11 @@
 
 #define ppc_inst(x) (x)
 
+static inline u32 ppc_inst_val(u32 x)
+{
+	return x;
+}
+
 static inline int ppc_inst_opcode(u32 x)
 {
 	return x >> 26;
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 769f055509c9..26d729562fe2 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -15,9 +15,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_val(instr) & 0xfc0007be) == 0x7c000124)
+#define IS_RFID(instr)		((ppc_inst_val(instr) & 0xfc0007fe) == 0x4c000024)
+#define IS_RFI(instr)		((ppc_inst_val(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 691013aa9f3c..a83d32c6513d 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -315,7 +315,7 @@ int fix_alignment(struct pt_regs *regs)
 
 #ifdef CONFIG_SPE
 	if (ppc_inst_opcode(instr) == 0x4) {
-		int reg = (instr >> 21) & 0x1f;
+		int reg = (ppc_inst_val(instr) >> 21) & 0x1f;
 		PPC_WARN_ALIGNMENT(spe, regs);
 		return emulate_spe(regs, reg, instr);
 	}
@@ -332,7 +332,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_val(instr) & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe))
 		return -EIO;
 
 	r = analyse_instr(&op, regs, instr);
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index a1a3686f41c6..8420b1944164 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -234,7 +234,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_val(insn));
 		BUG();
 	} else {
 		/*
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 47233e671c18..62ff429bddc4 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, unsigned int old, unsigned int new)
 	/* Make sure it is what we expect it to be */
 	if (replaced != old) {
 		pr_err("%p: replaced (%#x) != old (%#x)",
-		(void *)ip, replaced, old);
+		(void *)ip, ppc_inst_val(replaced), ppc_inst_val(old));
 		return -EINVAL;
 	}
 
@@ -99,19 +99,19 @@ static int test_24bit_addr(unsigned long ip, unsigned long addr)
 
 static int is_bl_op(unsigned int op)
 {
-	return (op & 0xfc000003) == 0x48000001;
+	return (ppc_inst_val(op) & 0xfc000003) == 0x48000001;
 }
 
 static int is_b_op(unsigned int op)
 {
-	return (op & 0xfc000003) == 0x48000000;
+	return (ppc_inst_val(op) & 0xfc000003) == 0x48000000;
 }
 
 static unsigned long find_bl_target(unsigned long ip, unsigned int op)
 {
 	int offset;
 
-	offset = (op & 0x03fffffc);
+	offset = (ppc_inst_val(op) & 0x03fffffc);
 	/* make it signed */
 	if (offset & 0x02000000)
 		offset |= 0xfe000000;
@@ -137,7 +137,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_val(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 (op != ppc_inst(PPC_INST_MFLR) && 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_val(op));
 		return -EINVAL;
 	}
 #else
@@ -201,7 +201,7 @@ __ftrace_make_nop(struct module *mod,
 	}
 
 	if (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_val(op));
 		return -EINVAL;
 	}
 #endif /* CONFIG_MPROFILE_KERNEL */
@@ -403,7 +403,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_val(op));
 		return -EINVAL;
 	}
 
@@ -497,7 +497,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
 	 * The load offset is different depending on the ABI. For simplicity
 	 * just mask it out when doing the compare.
 	 */
-	if ((op0 != ppc_inst(0x48000008)) || ((op1 & 0xffff0000) != 0xe8410000))
+	if ((op0 != ppc_inst(0x48000008)) || (ppc_inst_val(op1) & 0xffff0000) != 0xe8410000)
 		return 0;
 	return 1;
 }
@@ -647,7 +647,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	if (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_val(op));
 		return -EINVAL;
 	}
 
@@ -726,7 +726,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_val(op));
 		return -EINVAL;
 	}
 
diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
index 4acd3fb2b38e..c8d21e812d8c 100644
--- a/arch/powerpc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
@@ -10,6 +10,7 @@
 #include <asm/processor.h>
 #include <asm/switch_to.h>
 #include <linux/uaccess.h>
+#include <asm/inst.h>
 
 /* Functions in vector.S */
 extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
@@ -260,21 +261,23 @@ static unsigned int rfin(unsigned int x)
 
 int emulate_altivec(struct pt_regs *regs)
 {
-	unsigned int instr, i;
+	unsigned int instr, i, word;
 	unsigned int va, vb, vc, vd;
 	vector128 *vrs;
 
 	if (get_user(instr, (unsigned int __user *) regs->nip))
 		return -EFAULT;
-	if ((instr >> 26) != 4)
+
+	word = ppc_inst_val(instr);
+	if ((word >> 26) != 4)
 		return -EINVAL;		/* not an altivec instruction */
-	vd = (instr >> 21) & 0x1f;
-	va = (instr >> 16) & 0x1f;
-	vb = (instr >> 11) & 0x1f;
-	vc = (instr >> 6) & 0x1f;
+	vd = (word >> 21) & 0x1f;
+	va = (word >> 16) & 0x1f;
+	vb = (word >> 11) & 0x1f;
+	vc = (word >> 6) & 0x1f;
 
 	vrs = current->thread.vr_state.vr;
-	switch (instr & 0x3f) {
+	switch (word & 0x3f) {
 	case 10:
 		switch (vc) {
 		case 0:	/* vaddfp */
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 099a515202aa..3f88d2a4400c 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -236,7 +236,7 @@ bool is_conditional_branch(unsigned int instr)
 	if (opcode == 16)       /* bc, bca, bcl, bcla */
 		return true;
 	if (opcode == 19) {
-		switch ((instr >> 1) & 0x3ff) {
+		switch ((ppc_inst_val(instr) >> 1) & 0x3ff) {
 		case 16:        /* bclr, bclrl */
 		case 528:       /* bcctr, bcctrl */
 		case 560:       /* bctar, bctarl */
@@ -304,7 +304,7 @@ static int instr_is_branch_bform(unsigned int instr)
 
 int instr_is_relative_branch(unsigned int instr)
 {
-	if (instr & BRANCH_ABSOLUTE)
+	if (ppc_inst_val(instr) & BRANCH_ABSOLUTE)
 		return 0;
 
 	return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
@@ -312,20 +312,20 @@ int instr_is_relative_branch(unsigned int instr)
 
 int instr_is_relative_link_branch(unsigned int instr)
 {
-	return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK);
+	return instr_is_relative_branch(instr) && (ppc_inst_val(instr) & BRANCH_SET_LINK);
 }
 
 static unsigned long branch_iform_target(const unsigned int *instr)
 {
 	signed long imm;
 
-	imm = *instr & 0x3FFFFFC;
+	imm = ppc_inst_val(*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_val(*instr) & BRANCH_ABSOLUTE) == 0)
 		imm += (unsigned long)instr;
 
 	return (unsigned long)imm;
@@ -335,13 +335,13 @@ static unsigned long branch_bform_target(const unsigned int *instr)
 {
 	signed long imm;
 
-	imm = *instr & 0xFFFC;
+	imm = ppc_inst_val(*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_val(*instr) & BRANCH_ABSOLUTE) == 0)
 		imm += (unsigned long)instr;
 
 	return (unsigned long)imm;
@@ -372,9 +372,9 @@ int translate_branch(unsigned int *instr, const unsigned int *dest, const unsign
 	target = branch_target(src);
 
 	if (instr_is_branch_iform(*src))
-		return create_branch(instr, dest, target, *src);
+		return create_branch(instr, dest, target, ppc_inst_val(*src));
 	else if (instr_is_branch_bform(*src))
-		return create_cond_branch(instr, dest, target, *src);
+		return create_cond_branch(instr, dest, target, ppc_inst_val(*src));
 
 	return 1;
 }
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index c077acb983a1..26e37176692e 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_val(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 88b17226a493..60f7eb24d742 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -846,12 +846,12 @@ static int __init emulate_compute_instr(struct pt_regs *regs,
 {
 	struct instruction_op op;
 
-	if (!regs || !instr)
+	if (!regs || !ppc_inst_val(instr))
 		return -EINVAL;
 
 	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_val(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_val(instr));
 		return -EFAULT;
 	}
 
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 68ecb39dd9cc..3c1fb46bfacf 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2870,9 +2870,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_val(inst));
 		printf("\t");
-		dump_func(inst, adr);
+		dump_func(ppc_inst_val(inst), adr);
 		printf("\n");
 	}
 	return adr - first_adr;
-- 
2.17.1


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

* [PATCH v5 07/21] powerpc: Use a function for byte swapping instructions
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (5 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 06/21] powerpc: Use an accessor for instructions Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07  7:42   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 08/21] powerpc: Introduce functions for instruction equality Jordan Niethe
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Use a function for byte swapping instructions in preparation of a more
complicated instruction type.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/include/asm/inst.h | 5 +++++
 arch/powerpc/kernel/align.c     | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 15f570bef936..78eb1481f1f6 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -18,4 +18,9 @@ static inline int ppc_inst_opcode(u32 x)
 	return x >> 26;
 }
 
+static inline u32 ppc_inst_swab(u32 x)
+{
+	return ppc_inst(swab32(ppc_inst_val(x)));
+}
+
 #endif /* _ASM_INST_H */
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index a83d32c6513d..46870cf6a6dc 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -310,7 +310,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_swab(instr);
 	}
 
 #ifdef CONFIG_SPE
-- 
2.17.1


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

* [PATCH v5 08/21] powerpc: Introduce functions for instruction equality
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (6 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 07/21] powerpc: Use a function for byte swapping instructions Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07  7:37   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 09/21] powerpc: Use a datatype for instructions Jordan Niethe
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v5: Remove ppc_inst_null()
---
 arch/powerpc/include/asm/inst.h      |  5 +++++
 arch/powerpc/kernel/trace/ftrace.c   | 15 ++++++++-------
 arch/powerpc/lib/code-patching.c     | 12 ++++++------
 arch/powerpc/lib/test_emulate_step.c |  2 +-
 arch/powerpc/xmon/xmon.c             |  4 ++--
 5 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 78eb1481f1f6..54ee46b0a7c9 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -23,4 +23,9 @@ static inline u32 ppc_inst_swab(u32 x)
 	return ppc_inst(swab32(ppc_inst_val(x)));
 }
 
+static inline bool ppc_inst_equal(u32 x, u32 y)
+{
+	return x == y;
+}
+
 #endif /* _ASM_INST_H */
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 62ff429bddc4..784b5746cc55 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, unsigned int old, unsigned int 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, ppc_inst_val(replaced), ppc_inst_val(old));
 		return -EINVAL;
@@ -170,7 +170,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", ppc_inst_val(op));
 		return -EINVAL;
 	}
@@ -200,7 +201,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, ppc_inst_val(op));
 		return -EINVAL;
 	}
@@ -497,7 +498,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
 	 * The load offset is different depending on the ABI. For simplicity
 	 * just mask it out when doing the compare.
 	 */
-	if ((op0 != ppc_inst(0x48000008)) || (ppc_inst_val(op1) & 0xffff0000) != 0xe8410000)
+	if ((!ppc_inst_equal(op0), ppc_inst(0x48000008)) || (ppc_inst_val(op1) & 0xffff0000) != 0xe8410000)
 		return 0;
 	return 1;
 }
@@ -506,7 +507,7 @@ static int
 expected_nop_sequence(void *ip, unsigned int op0, unsigned int 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;
 }
@@ -589,7 +590,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;
 	}
@@ -646,7 +647,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, ppc_inst_val(op));
 		return -EINVAL;
 	}
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 3f88d2a4400c..33654c6334a9 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -478,7 +478,7 @@ static void __init test_branch_iform(void)
 	/* Check flags are masked correctly */
 	err = create_branch(&instr, &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)
@@ -563,7 +563,7 @@ static void __init test_branch_bform(void)
 	/* Check flags are masked correctly */
 	err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
 	check(instr_is_branch_to_addr(&instr, addr));
-	check(instr == ppc_inst(0x43FF0000));
+	check(ppc_inst_equal(instr, ppc_inst(0x43FF0000)));
 }
 
 static void __init test_translate_branch(void)
@@ -597,7 +597,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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(*q, ppc_inst(0x4a000000)));
 
 	/* Maximum positive case, move x to x - 32 MB + 4 */
 	p = buf + 0x2000000;
@@ -608,7 +608,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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(*q, ppc_inst(0x49fffffc)));
 
 	/* Jump to x + 16 MB moved to x + 20 MB */
 	p = buf;
@@ -654,7 +654,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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(*q, ppc_inst(0x43ff8000)));
 
 	/* Maximum positive case, move x to x - 32 KB + 4 */
 	p = buf + 0x8000;
@@ -666,7 +666,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	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(*q, ppc_inst(0x43ff7ffc)));
 
 	/* Jump to x + 12 KB moved to x + 20 KB */
 	p = buf;
diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c
index 60f7eb24d742..16387a9bfda0 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -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_val(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 3c1fb46bfacf..f6c87d3d53ea 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -950,7 +950,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(
 			(unsigned int *)bp->address, bp->instr[0]) != 0)
 			printf("Couldn't remove breakpoint at %lx\n",
@@ -2860,7 +2860,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] 71+ messages in thread

* [PATCH v5 09/21] powerpc: Use a datatype for instructions
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (7 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 08/21] powerpc: Introduce functions for instruction equality Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06 10:34     ` kbuild test robot
                     ` (2 more replies)
  2020-04-06  8:09 ` [PATCH v5 10/21] powerpc: Use a function for reading instructions Jordan Niethe
                   ` (12 subsequent siblings)
  21 siblings, 3 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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>
---
v4: New to series
v5: Add to epapr_paravirt.c, kgdb.c
---
 arch/powerpc/include/asm/code-patching.h | 32 ++++-----
 arch/powerpc/include/asm/inst.h          | 20 +++---
 arch/powerpc/include/asm/sstep.h         |  5 +-
 arch/powerpc/include/asm/uprobes.h       |  5 +-
 arch/powerpc/kernel/align.c              |  4 +-
 arch/powerpc/kernel/epapr_paravirt.c     |  4 +-
 arch/powerpc/kernel/hw_breakpoint.c      |  4 +-
 arch/powerpc/kernel/jump_label.c         |  2 +-
 arch/powerpc/kernel/kgdb.c               |  4 +-
 arch/powerpc/kernel/kprobes.c            |  8 +--
 arch/powerpc/kernel/mce_power.c          |  5 +-
 arch/powerpc/kernel/optprobes.c          | 40 ++++++------
 arch/powerpc/kernel/setup_32.c           |  2 +-
 arch/powerpc/kernel/trace/ftrace.c       | 83 ++++++++++++------------
 arch/powerpc/kernel/vecemu.c             |  5 +-
 arch/powerpc/lib/code-patching.c         | 69 ++++++++++----------
 arch/powerpc/lib/feature-fixups.c        | 48 +++++++-------
 arch/powerpc/lib/sstep.c                 |  4 +-
 arch/powerpc/lib/test_emulate_step.c     |  9 +--
 arch/powerpc/perf/core-book3s.c          |  4 +-
 arch/powerpc/xmon/xmon.c                 | 24 +++----
 21 files changed, 196 insertions(+), 185 deletions(-)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 48e021957ee5..eacc9102c251 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -23,33 +23,33 @@
 #define BRANCH_ABSOLUTE	0x2
 
 bool is_offset_in_branch_range(long offset);
-int create_branch(unsigned int *instr, const unsigned int *addr,
+int create_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
 		  unsigned long target, int flags);
-int create_cond_branch(unsigned int *instr, const unsigned int *addr,
+int create_cond_branch(struct ppc_inst *instr, const struct 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(struct ppc_inst *addr, unsigned long target, int flags);
+int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
+int raw_patch_instruction(struct ppc_inst *addr, struct 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, struct ppc_inst instr)
 {
-	return patch_instruction((unsigned int *)patch_site_addr(site), instr);
+	return patch_instruction((struct 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((struct ppc_inst *)patch_site_addr(site), target, flags);
 }
 
 static inline int modify_instruction(unsigned int *addr, unsigned int clr,
 				     unsigned int set)
 {
-	return patch_instruction(addr, ppc_inst((*addr & ~clr) | set));
+	return patch_instruction((struct ppc_inst *)addr, ppc_inst((*addr & ~clr) | set));
 }
 
 static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set)
@@ -57,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);
-int translate_branch(unsigned int *instr, const unsigned int *dest,
-		     const unsigned int *src);
-extern bool is_conditional_branch(unsigned int instr);
+int instr_is_relative_branch(struct ppc_inst instr);
+int instr_is_relative_link_branch(struct ppc_inst instr);
+int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long addr);
+unsigned long branch_target(const struct ppc_inst *instr);
+int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
+		     const struct ppc_inst *src);
+extern bool is_conditional_branch(struct 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
index 54ee46b0a7c9..a71decf5f871 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -6,26 +6,30 @@
  * Instruction data type for POWER
  */
 
-#define ppc_inst(x) (x)
+struct ppc_inst {
+        u32 val;
+} __packed;
 
-static inline u32 ppc_inst_val(u32 x)
+#define ppc_inst(x) ((struct ppc_inst){ .val = x })
+
+static inline u32 ppc_inst_val(struct ppc_inst x)
 {
-	return x;
+	return x.val;
 }
 
-static inline int ppc_inst_opcode(u32 x)
+static inline int ppc_inst_opcode(struct ppc_inst x)
 {
-	return x >> 26;
+	return x.val >> 26;
 }
 
-static inline u32 ppc_inst_swab(u32 x)
+static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
 {
 	return ppc_inst(swab32(ppc_inst_val(x)));
 }
 
-static inline bool ppc_inst_equal(u32 x, u32 y)
+static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
 {
-	return x == y;
+	return !memcmp(&x, &y, sizeof(struct ppc_inst));
 }
 
 #endif /* _ASM_INST_H */
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 26d729562fe2..c3ce903ac488 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);
+			 struct 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, struct ppc_inst instr);
 
 /*
  * Emulate a load or store instruction by reading/writing the
diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
index 2bbdf27d09b5..7e3b329ba2d3 100644
--- a/arch/powerpc/include/asm/uprobes.h
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -11,6 +11,7 @@
 
 #include <linux/notifier.h>
 #include <asm/probes.h>
+#include <asm/inst.h>
 
 typedef ppc_opcode_t uprobe_opcode_t;
 
@@ -23,8 +24,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
 
 struct arch_uprobe {
 	union {
-		u32	insn;
-		u32	ixol;
+		struct ppc_inst	insn;
+		struct ppc_inst	ixol;
 	};
 };
 
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 46870cf6a6dc..66a6d1de7799 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -294,7 +294,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
 
 int fix_alignment(struct pt_regs *regs)
 {
-	unsigned int instr;
+	struct ppc_inst instr;
 	struct instruction_op op;
 	int r, type;
 
@@ -304,7 +304,7 @@ 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.val, (unsigned int __user *)regs->nip)))
 		return -EFAULT;
 	if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
 		/* We don't handle PPC little-endian any more... */
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c
index c53e863fb484..c42aa3926632 100644
--- a/arch/powerpc/kernel/epapr_paravirt.c
+++ b/arch/powerpc/kernel/epapr_paravirt.c
@@ -38,9 +38,9 @@ static int __init early_init_dt_scan_epapr(unsigned long node,
 
 	for (i = 0; i < (len / 4); i++) {
 		u32 inst = be32_to_cpu(insts[i]);
-		patch_instruction(epapr_hypercall_start + i, ppc_inst(inst));
+		patch_instruction((struct ppc_inst *)(epapr_hypercall_start + i), ppc_inst(inst));
 #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
-		patch_instruction(epapr_ev_idle_start + i, ppc_inst(inst));
+		patch_instruction((struct ppc_inst *)(epapr_ev_idle_start + i), ppc_inst(inst));
 #endif
 	}
 
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 79f51f182a83..542f65ccf68b 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -244,12 +244,12 @@ 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 = ppc_inst(0);
+	struct ppc_inst instr = ppc_inst(0);
 	int ret, type, size;
 	struct instruction_op op;
 	unsigned long addr = info->address;
 
-	if (__get_user_inatomic(instr, (unsigned int *)regs->nip))
+	if (__get_user_inatomic(instr.val, (unsigned int *)regs->nip))
 		goto fail;
 
 	ret = analyse_instr(&op, regs, instr);
diff --git a/arch/powerpc/kernel/jump_label.c b/arch/powerpc/kernel/jump_label.c
index daa4afce7ec8..144858027fa3 100644
--- a/arch/powerpc/kernel/jump_label.c
+++ b/arch/powerpc/kernel/jump_label.c
@@ -11,7 +11,7 @@
 void arch_jump_label_transform(struct jump_entry *entry,
 			       enum jump_label_type type)
 {
-	u32 *addr = (u32 *)(unsigned long)entry->code;
+	struct ppc_inst *addr = (struct ppc_inst *)(unsigned long)entry->code;
 
 	if (type == JUMP_LABEL_JMP)
 		patch_branch(addr, entry->target, 0);
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index a6b38a19133f..652b2852bea3 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -419,7 +419,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
 {
 	int err;
 	unsigned int instr;
-	unsigned int *addr = (unsigned int *)bpt->bpt_addr;
+	struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
 
 	err = probe_kernel_address(addr, instr);
 	if (err)
@@ -438,7 +438,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
 {
 	int err;
 	unsigned int instr = *(unsigned int *)bpt->saved_instr;
-	unsigned int *addr = (unsigned int *)bpt->bpt_addr;
+	struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
 
 	err = patch_instruction(addr, ppc_inst(instr));
 	if (err)
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 8420b1944164..9ed996cb0589 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
 int arch_prepare_kprobe(struct kprobe *p)
 {
 	int ret = 0;
-	kprobe_opcode_t insn = *p->addr;
+	struct ppc_inst insn = *(struct ppc_inst *)p->addr;
 
 	if ((unsigned long)p->addr & 0x03) {
 		printk("Attempt to register kprobe at an unaligned address\n");
@@ -139,13 +139,13 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
 
 void arch_arm_kprobe(struct kprobe *p)
 {
-	patch_instruction(p->addr, ppc_inst(BREAKPOINT_INSTRUCTION));
+	patch_instruction((struct ppc_inst *)p->addr, ppc_inst(BREAKPOINT_INSTRUCTION));
 }
 NOKPROBE_SYMBOL(arch_arm_kprobe);
 
 void arch_disarm_kprobe(struct kprobe *p)
 {
-	patch_instruction(p->addr, ppc_inst(p->opcode));
+	patch_instruction((struct ppc_inst *)p->addr, ppc_inst(p->opcode));
 }
 NOKPROBE_SYMBOL(arch_disarm_kprobe);
 
@@ -217,7 +217,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;
+	struct ppc_inst insn = *(struct 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 1cbf7f1a4e3d..7118b46a6543 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;
+	struct 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 = *(struct 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 3b33ebf18859..b61bbcee84f4 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -100,8 +100,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(*(struct ppc_inst *)p->ainsn.insn) &&
+			analyse_instr(&op, &regs, *(struct ppc_inst *)p->ainsn.insn) == 1) {
 		emulate_update_regs(&regs, &op);
 		nip = regs.nip;
 	}
@@ -148,12 +148,12 @@ 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(PPC_INST_ADDIS | ___PPC_RT(4) |
+	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS | ___PPC_RT(4) |
 			  ((val >> 16) & 0xffff)));
 	addr++;
 
 	/* ori r4,r4,(insn)@l */
-	patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(4) |
+	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(4) |
 			  ___PPC_RS(4) | (val & 0xffff)));
 }
 
@@ -164,34 +164,34 @@ 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(PPC_INST_ADDIS | ___PPC_RT(3) |
+	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS | ___PPC_RT(3) |
 			  ((val >> 48) & 0xffff)));
 	addr++;
 
 	/* ori r3,r3,(op)@higher */
-	patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(3) |
+	patch_instruction((struct ppc_inst *)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(PPC_INST_RLDICR | ___PPC_RA(3) |
+	patch_instruction((struct ppc_inst *)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(PPC_INST_ORIS | ___PPC_RA(3) |
+	patch_instruction((struct ppc_inst *)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(PPC_INST_ORI | ___PPC_RA(3) |
+	patch_instruction((struct ppc_inst *)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)
 {
-	kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
-	kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
+	struct 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;
@@ -231,7 +231,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, ppc_inst(*(optprobe_template_entry + i)));
+		rc = patch_instruction((struct ppc_inst *)(buff + i), ppc_inst(*(optprobe_template_entry + i)));
 		if (rc < 0)
 			goto error;
 	}
@@ -253,20 +253,20 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	}
 
 	rc = create_branch(&branch_op_callback,
-			   (unsigned int *)buff + TMPL_CALL_HDLR_IDX,
+			   (struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX),
 			   (unsigned long)op_callback_addr,
 			   BRANCH_SET_LINK);
 
 	rc |= create_branch(&branch_emulate_step,
-			    (unsigned int *)buff + TMPL_EMULATE_IDX,
+			    (struct ppc_inst *)(buff + TMPL_EMULATE_IDX),
 			    (unsigned long)emulate_step_addr,
 			    BRANCH_SET_LINK);
 
 	if (rc)
 		goto error;
 
-	patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
-	patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step);
+	patch_instruction((struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX), branch_op_callback);
+	patch_instruction((struct ppc_inst *)(buff + TMPL_EMULATE_IDX), branch_emulate_step);
 
 	/*
 	 * 3. load instruction to be emulated into relevant register, and
@@ -276,7 +276,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	/*
 	 * 4. branch back from trampoline
 	 */
-	patch_branch(buff + TMPL_RET_IDX, (unsigned long)nip, 0);
+	patch_branch((void *)(buff + TMPL_RET_IDX), (unsigned long)nip, 0);
 
 	flush_icache_range((unsigned long)buff,
 			   (unsigned long)(&buff[TMPL_END_IDX]));
@@ -308,7 +308,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe *op)
 
 void arch_optimize_kprobes(struct list_head *oplist)
 {
-	unsigned int instr;
+	struct ppc_inst instr;
 	struct optimized_kprobe *op;
 	struct optimized_kprobe *tmp;
 
@@ -320,9 +320,9 @@ void arch_optimize_kprobes(struct list_head *oplist)
 		memcpy(op->optinsn.copied_insn, op->kp.addr,
 					       RELATIVEJUMP_SIZE);
 		create_branch(&instr,
-			      (unsigned int *)op->kp.addr,
+			      (struct ppc_inst *)op->kp.addr,
 			      (unsigned long)op->optinsn.insn, 0);
-		patch_instruction(op->kp.addr, instr);
+		patch_instruction((struct ppc_inst *)op->kp.addr, instr);
 		list_del_init(&op->list);
 	}
 }
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index c1bdd462c5c0..989809e58234 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -76,7 +76,7 @@ EXPORT_SYMBOL(DMA_MODE_WRITE);
 notrace void __init machine_init(u64 dt_ptr)
 {
 	unsigned int *addr = (unsigned int *)patch_site_addr(&patch__memset_nocache);
-	unsigned long insn;
+	struct ppc_inst insn;
 
 	/* Configure static keys first, now that we're relocated. */
 	setup_feature_keys();
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 784b5746cc55..442c62fb68ff 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -41,23 +41,23 @@
 #define	NUM_FTRACE_TRAMPS	8
 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
 
-static unsigned int
+static struct ppc_inst
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
-	unsigned int op;
+	struct ppc_inst op;
 
 	addr = ppc_function_entry((void *)addr);
 
 	/* if (link) set op to 'bl' else 'b' */
-	create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
+	create_branch(&op, (struct 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, struct ppc_inst old, struct ppc_inst new)
 {
-	unsigned int replaced;
+	struct ppc_inst replaced;
 
 	/*
 	 * Note:
@@ -79,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((struct ppc_inst *)ip, new))
 		return -EPERM;
 
 	return 0;
@@ -90,24 +90,24 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
  */
 static int test_24bit_addr(unsigned long ip, unsigned long addr)
 {
-	unsigned int op;
+	struct ppc_inst op;
 	addr = ppc_function_entry((void *)addr);
 
 	/* use the create_branch to verify that this offset can be branched */
-	return create_branch(&op, (unsigned int *)ip, addr, 0) == 0;
+	return create_branch(&op, (struct ppc_inst *)ip, addr, 0) == 0;
 }
 
-static int is_bl_op(unsigned int op)
+static int is_bl_op(struct ppc_inst op)
 {
 	return (ppc_inst_val(op) & 0xfc000003) == 0x48000001;
 }
 
-static int is_b_op(unsigned int op)
+static int is_b_op(struct ppc_inst op)
 {
 	return (ppc_inst_val(op) & 0xfc000003) == 0x48000000;
 }
 
-static unsigned long find_bl_target(unsigned long ip, unsigned int op)
+static unsigned long find_bl_target(unsigned long ip, struct ppc_inst op)
 {
 	int offset;
 
@@ -127,7 +127,7 @@ __ftrace_make_nop(struct module *mod,
 {
 	unsigned long entry, ptr, tramp;
 	unsigned long ip = rec->ip;
-	unsigned int op, pop;
+	struct ppc_inst op, pop;
 
 	/* read where this goes */
 	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
@@ -207,7 +207,7 @@ __ftrace_make_nop(struct module *mod,
 	}
 #endif /* CONFIG_MPROFILE_KERNEL */
 
-	if (patch_instruction((unsigned int *)ip, pop)) {
+	if (patch_instruction((struct ppc_inst *)ip, pop)) {
 		pr_err("Patching NOP failed.\n");
 		return -EPERM;
 	}
@@ -220,7 +220,7 @@ static int
 __ftrace_make_nop(struct module *mod,
 		  struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned int op;
+	struct ppc_inst op;
 	unsigned int jmp[4];
 	unsigned long ip = rec->ip;
 	unsigned long tramp;
@@ -279,7 +279,7 @@ __ftrace_make_nop(struct module *mod,
 
 	op = ppc_inst(PPC_INST_NOP);
 
-	if (patch_instruction((unsigned int *)ip, op))
+	if (patch_instruction((struct ppc_inst *)ip, op))
 		return -EPERM;
 
 	return 0;
@@ -290,7 +290,7 @@ __ftrace_make_nop(struct module *mod,
 static unsigned long find_ftrace_tramp(unsigned long ip)
 {
 	int i;
-	unsigned int instr;
+	struct ppc_inst instr;
 
 	/*
 	 * We have the compiler generated long_branch tramps at the end
@@ -327,9 +327,10 @@ static int add_ftrace_tramp(unsigned long tramp)
  */
 static int setup_mcount_compiler_tramp(unsigned long tramp)
 {
-	int i, op;
+	int i;
+	struct ppc_inst op;
 	unsigned long ptr;
-	unsigned int instr;
+	struct ppc_inst instr;
 	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
 
 	/* Is this a known long jump tramp? */
@@ -378,7 +379,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
 		return -1;
 	}
 
-	if (patch_branch((unsigned int *)tramp, ptr, 0)) {
+	if (patch_branch((struct ppc_inst *)tramp, ptr, 0)) {
 		pr_debug("REL24 out of range!\n");
 		return -1;
 	}
@@ -394,7 +395,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;
+	struct ppc_inst op;
 
 	/* Read where this goes */
 	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
@@ -422,7 +423,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 		}
 	}
 
-	if (patch_instruction((unsigned int *)ip, ppc_inst(PPC_INST_NOP))) {
+	if (patch_instruction((struct ppc_inst *)ip, ppc_inst(PPC_INST_NOP))) {
 		pr_err("Patching NOP failed.\n");
 		return -EPERM;
 	}
@@ -434,7 +435,7 @@ int ftrace_make_nop(struct module *mod,
 		    struct dyn_ftrace *rec, unsigned long addr)
 {
 	unsigned long ip = rec->ip;
-	unsigned int old, new;
+	struct ppc_inst old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -487,7 +488,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, struct ppc_inst op0, struct ppc_inst op1)
 {
 	/*
 	 * We expect to see:
@@ -504,7 +505,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
 }
 #else
 static int
-expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
+expected_nop_sequence(void *ip, struct ppc_inst op0, struct ppc_inst op1)
 {
 	/* look for patched "NOP" on ppc64 with -mprofile-kernel */
 	if (!ppc_inst_equal(op0, ppc_inst(PPC_INST_NOP)))
@@ -516,8 +517,8 @@ 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];
-	unsigned int instr;
+	struct ppc_inst op[2];
+	struct ppc_inst instr;
 	void *ip = (void *)rec->ip;
 	unsigned long entry, ptr, tramp;
 	struct module *mod = rec->arch.mod;
@@ -528,7 +529,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_val(op[0]), ppc_inst_val(op[1]));
 		return -EINVAL;
 	}
 
@@ -582,7 +583,7 @@ static int
 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
 	int err;
-	unsigned int op;
+	struct ppc_inst op;
 	unsigned long ip = rec->ip;
 
 	/* read where this goes */
@@ -602,7 +603,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	/* create the branch to the trampoline */
-	err = create_branch(&op, (unsigned int *)ip,
+	err = create_branch(&op, (struct ppc_inst *)ip,
 			    rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
 	if (!err) {
 		pr_err("REL24 out of range!\n");
@@ -621,7 +622,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;
+	struct ppc_inst op;
 	void *ip = (void *)rec->ip;
 	unsigned long tramp, entry, ptr;
 
@@ -669,7 +670,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;
+	struct ppc_inst old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -708,7 +709,7 @@ static int
 __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 					unsigned long addr)
 {
-	unsigned int op;
+	struct ppc_inst op;
 	unsigned long ip = rec->ip;
 	unsigned long entry, ptr, tramp;
 	struct module *mod = rec->arch.mod;
@@ -756,7 +757,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((struct ppc_inst *)ip, addr, BRANCH_SET_LINK)) {
 			pr_err("REL24 out of range!\n");
 			return -EINVAL;
 		}
@@ -784,12 +785,12 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	}
 
 	/* Ensure branch is within 24 bits */
-	if (create_branch(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
+	if (create_branch(&op, (struct ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
 
-	if (patch_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
+	if (patch_branch((struct ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
 		pr_err("REL24 out of range!\n");
 		return -EINVAL;
 	}
@@ -802,7 +803,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;
+	struct ppc_inst old, new;
 
 	/*
 	 * If the calling address is more that 24 bits away,
@@ -842,10 +843,10 @@ 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;
+	struct ppc_inst old, new;
 	int ret;
 
-	old = *(unsigned int *)&ftrace_call;
+	old = *(struct ppc_inst *)&ftrace_call;
 	new = ftrace_call_replace(ip, (unsigned long)func, 1);
 	ret = ftrace_modify_code(ip, old, new);
 
@@ -853,7 +854,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 = *(struct ppc_inst *)&ftrace_regs_call;
 		new = ftrace_call_replace(ip, (unsigned long)func, 1);
 		ret = ftrace_modify_code(ip, old, new);
 	}
@@ -927,7 +928,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;
+	struct ppc_inst old, new;
 
 	old = ftrace_call_replace(ip, stub, 0);
 	new = ftrace_call_replace(ip, addr, 0);
@@ -940,7 +941,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;
+	struct ppc_inst old, new;
 
 	old = ftrace_call_replace(ip, addr, 0);
 	new = ftrace_call_replace(ip, stub, 0);
diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
index c8d21e812d8c..bbf536e10902 100644
--- a/arch/powerpc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
@@ -261,11 +261,12 @@ static unsigned int rfin(unsigned int x)
 
 int emulate_altivec(struct pt_regs *regs)
 {
-	unsigned int instr, i, word;
+	struct ppc_inst instr;
+	unsigned int i, word;
 	unsigned int va, vb, vc, vd;
 	vector128 *vrs;
 
-	if (get_user(instr, (unsigned int __user *) regs->nip))
+	if (get_user(instr.val, (unsigned int __user *) regs->nip))
 		return -EFAULT;
 
 	word = ppc_inst_val(instr);
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 33654c6334a9..91be4a0b51cb 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -19,12 +19,12 @@
 #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(struct ppc_inst *exec_addr, struct ppc_inst instr,
+			       struct ppc_inst *patch_addr)
 {
 	int err = 0;
 
-	__put_user_asm(instr, patch_addr, err, "stw");
+	__put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw");
 	if (err)
 		return err;
 
@@ -34,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(struct ppc_inst *addr, struct ppc_inst instr)
 {
 	return __patch_instruction(addr, instr, addr);
 }
@@ -137,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(struct ppc_inst *addr, struct ppc_inst instr)
 {
 	int err;
-	unsigned int *patch_addr = NULL;
+	struct ppc_inst *patch_addr = NULL;
 	unsigned long flags;
 	unsigned long text_poke_addr;
 	unsigned long kaddr = (unsigned long)addr;
@@ -177,14 +177,14 @@ 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(struct ppc_inst *addr, struct ppc_inst instr)
 {
 	return raw_patch_instruction(addr, instr);
 }
 
 #endif /* CONFIG_STRICT_KERNEL_RWX */
 
-int patch_instruction(unsigned int *addr, unsigned int instr)
+int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr)
 {
 	/* Make sure we aren't patching a freed init section */
 	if (init_mem_is_free && init_section_contains(addr, 4)) {
@@ -195,9 +195,9 @@ 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(struct ppc_inst *addr, unsigned long target, int flags)
 {
-	unsigned int instr;
+	struct ppc_inst instr;
 
 	create_branch(&instr, addr, target, flags);
 	return patch_instruction(addr, instr);
@@ -229,7 +229,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(struct ppc_inst instr)
 {
 	unsigned int opcode = ppc_inst_opcode(instr);
 
@@ -247,13 +247,13 @@ bool is_conditional_branch(unsigned int instr)
 }
 NOKPROBE_SYMBOL(is_conditional_branch);
 
-int create_branch(unsigned int *instr,
-		  const unsigned int *addr,
+int create_branch(struct ppc_inst *instr,
+		  const struct ppc_inst *addr,
 		  unsigned long target, int flags)
 {
 	long offset;
 
-	*instr = 0;
+	*instr = ppc_inst(0);
 	offset = target;
 	if (! (flags & BRANCH_ABSOLUTE))
 		offset = offset - (unsigned long)addr;
@@ -263,12 +263,12 @@ int create_branch(unsigned int *instr,
 		return 1;
 
 	/* Mask out the flags and target, so they don't step on each other. */
-	*instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
+	*instr = ppc_inst(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC));
 
 	return 0;
 }
 
-int create_cond_branch(unsigned int *instr, const unsigned int *addr,
+int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
 		       unsigned long target, int flags)
 {
 	long offset;
@@ -282,27 +282,27 @@ int create_cond_branch(unsigned int *instr, const unsigned int *addr,
 		return 1;
 
 	/* Mask out the flags and target, so they don't step on each other. */
-	*instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
+	*instr = ppc_inst(0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC));
 
 	return 0;
 }
 
-static unsigned int branch_opcode(unsigned int instr)
+static unsigned int branch_opcode(struct ppc_inst instr)
 {
 	return ppc_inst_opcode(instr) & 0x3F;
 }
 
-static int instr_is_branch_iform(unsigned int instr)
+static int instr_is_branch_iform(struct ppc_inst instr)
 {
 	return branch_opcode(instr) == 18;
 }
 
-static int instr_is_branch_bform(unsigned int instr)
+static int instr_is_branch_bform(struct ppc_inst instr)
 {
 	return branch_opcode(instr) == 16;
 }
 
-int instr_is_relative_branch(unsigned int instr)
+int instr_is_relative_branch(struct ppc_inst instr)
 {
 	if (ppc_inst_val(instr) & BRANCH_ABSOLUTE)
 		return 0;
@@ -310,12 +310,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(struct ppc_inst instr)
 {
 	return instr_is_relative_branch(instr) && (ppc_inst_val(instr) & BRANCH_SET_LINK);
 }
 
-static unsigned long branch_iform_target(const unsigned int *instr)
+static unsigned long branch_iform_target(const struct ppc_inst *instr)
 {
 	signed long imm;
 
@@ -331,7 +331,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 struct ppc_inst *instr)
 {
 	signed long imm;
 
@@ -347,7 +347,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 struct ppc_inst *instr)
 {
 	if (instr_is_branch_iform(*instr))
 		return branch_iform_target(instr);
@@ -357,7 +357,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 struct ppc_inst *instr, unsigned long addr)
 {
 	if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
 		return branch_target(instr) == addr;
@@ -365,7 +365,7 @@ int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
 	return 0;
 }
 
-int translate_branch(unsigned int *instr, const unsigned int *dest, const unsigned int *src)
+int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest, const struct ppc_inst *src)
 {
 	unsigned long target;
 
@@ -408,7 +408,7 @@ static void __init test_trampoline(void)
 static void __init test_branch_iform(void)
 {
 	int err;
-	unsigned int instr;
+	struct ppc_inst instr;
 	unsigned long addr;
 
 	addr = (unsigned long)&instr;
@@ -483,12 +483,12 @@ static void __init test_branch_iform(void)
 
 static void __init test_create_function_call(void)
 {
-	unsigned int *iptr;
+	struct ppc_inst *iptr;
 	unsigned long dest;
-	unsigned int instr;
+	struct ppc_inst instr;
 
 	/* Check we can create a function call */
-	iptr = (unsigned int *)ppc_function_entry(test_trampoline);
+	iptr = (struct ppc_inst *)ppc_function_entry(test_trampoline);
 	dest = ppc_function_entry(test_create_function_call);
 	create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
 	patch_instruction(iptr, instr);
@@ -499,7 +499,8 @@ static void __init test_branch_bform(void)
 {
 	int err;
 	unsigned long addr;
-	unsigned int *iptr, instr, flags;
+	struct ppc_inst *iptr, instr;
+	unsigned int flags;
 
 	iptr = &instr;
 	addr = (unsigned long)iptr;
@@ -569,8 +570,8 @@ static void __init test_branch_bform(void)
 static void __init test_translate_branch(void)
 {
 	unsigned long addr;
-	unsigned int *p, *q;
-	unsigned int instr;
+	struct ppc_inst *p, *q;
+	struct ppc_inst instr;
 	void *buf;
 
 	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 6e7479b8887a..8c5d0db77013 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -32,26 +32,26 @@ struct fixup_entry {
 	long		alt_end_off;
 };
 
-static unsigned int *calc_addr(struct fixup_entry *fcur, long offset)
+static struct ppc_inst *calc_addr(struct fixup_entry *fcur, long offset)
 {
 	/*
 	 * We store the offset to the code as a negative offset from
 	 * the start of the alt_entry, to support the VDSO. This
 	 * routine converts that back into an actual address.
 	 */
-	return (unsigned int *)((unsigned long)fcur + offset);
+	return (struct ppc_inst *)((unsigned long)fcur + offset);
 }
 
-static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
-				 unsigned int *alt_start, unsigned int *alt_end)
+static int patch_alt_instruction(struct ppc_inst *src, struct ppc_inst *dest,
+				 struct ppc_inst *alt_start, struct ppc_inst *alt_end)
 {
 	int err;
-	unsigned int instr;
+	struct ppc_inst instr;
 
 	instr = *src;
 
 	if (instr_is_relative_branch(*src)) {
-		unsigned int *target = (unsigned int *)branch_target(src);
+		struct ppc_inst *target = (struct ppc_inst *)branch_target(src);
 
 		/* Branch within the section doesn't need translating */
 		if (target < alt_start || target > alt_end) {
@@ -68,7 +68,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
 
 static int patch_feature_section(unsigned long value, struct fixup_entry *fcur)
 {
-	unsigned int *start, *end, *alt_start, *alt_end, *src, *dest;
+	struct ppc_inst *start, *end, *alt_start, *alt_end, *src, *dest;
 
 	start = calc_addr(fcur, fcur->start_off);
 	end = calc_addr(fcur, fcur->end_off);
@@ -147,15 +147,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, ppc_inst(instrs[0]));
+		patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0]));
 
 		if (types & STF_BARRIER_FALLBACK)
-			patch_branch(dest + 1, (unsigned long)&stf_barrier_fallback,
+			patch_branch((struct ppc_inst *)(dest + 1), (unsigned long)&stf_barrier_fallback,
 				     BRANCH_SET_LINK);
 		else
-			patch_instruction(dest + 1, ppc_inst(instrs[1]));
+			patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1]));
 
-		patch_instruction(dest + 2, ppc_inst(instrs[2]));
+		patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
 	}
 
 	printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i,
@@ -208,12 +208,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, 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]));
+		patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0]));
+		patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1]));
+		patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
+		patch_instruction((struct ppc_inst *)(dest + 3), ppc_inst(instrs[3]));
+		patch_instruction((struct ppc_inst *)(dest + 4), ppc_inst(instrs[4]));
+		patch_instruction((struct ppc_inst *)(dest + 5), ppc_inst(instrs[5]));
 	}
 	printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i,
 		(types == STF_BARRIER_NONE)                  ? "no" :
@@ -261,9 +261,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
 
 		pr_devel("patching dest %lx\n", (unsigned long)dest);
 
-		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((struct ppc_inst *)dest, ppc_inst(instrs[0]));
+		patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1]));
+		patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
 	}
 
 	printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
@@ -296,7 +296,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, ppc_inst(instr));
+		patch_instruction((struct ppc_inst *)dest, ppc_inst(instr));
 	}
 
 	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
@@ -339,8 +339,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, ppc_inst(instr[0]));
-		patch_instruction(dest + 1, ppc_inst(instr[1]));
+		patch_instruction((struct ppc_inst *)dest, ppc_inst(instr[0]));
+		patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instr[1]));
 	}
 
 	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
@@ -373,7 +373,7 @@ void do_btb_flush_fixups(void)
 void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
 {
 	long *start, *end;
-	unsigned int *dest;
+	struct ppc_inst *dest;
 
 	if (!(value & CPU_FTR_LWSYNC))
 		return ;
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 26e37176692e..52ddd3122dc8 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)
+		  struct ppc_inst instr)
 {
 	unsigned int opcode, ra, rb, rc, rd, spr, u;
 	unsigned long int imm;
@@ -3103,7 +3103,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, struct 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 16387a9bfda0..60b159b60545 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -461,7 +461,7 @@ struct compute_test {
 	struct {
 		char *descr;
 		unsigned long flags;
-		unsigned int instr;
+		struct ppc_inst instr;
 		struct pt_regs regs;
 	} subtests[MAX_SUBTESTS + 1];
 };
@@ -842,7 +842,7 @@ static struct compute_test compute_tests[] = {
 };
 
 static int __init emulate_compute_instr(struct pt_regs *regs,
-					unsigned int instr)
+					struct ppc_inst instr)
 {
 	struct instruction_op op;
 
@@ -860,7 +860,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs,
 }
 
 static int __init execute_compute_instr(struct pt_regs *regs,
-					unsigned int instr)
+					struct ppc_inst instr)
 {
 	extern int exec_instr(struct pt_regs *regs);
 	extern s32 patch__exec_instr;
@@ -891,7 +891,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;
+	struct 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/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 3086055bf681..2d2580a4bfb5 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -421,14 +421,14 @@ static __u64 power_pmu_bhrb_to(u64 addr)
 		if (probe_kernel_read(&instr, (void *)addr, sizeof(instr)))
 			return 0;
 
-		return branch_target(&instr);
+		return branch_target((struct ppc_inst *)&instr);
 	}
 
 	/* Userspace: need copy instruction here then translate it */
 	if (probe_user_read(&instr, (unsigned int __user *)addr, sizeof(instr)))
 		return 0;
 
-	target = branch_target(&instr);
+	target = branch_target((struct ppc_inst *)&instr);
 	if ((!target) || (instr & BRANCH_ABSOLUTE))
 		return target;
 
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index f6c87d3d53ea..e3d8e1b8ce01 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -99,7 +99,7 @@ static long *xmon_fault_jmp[NR_CPUS];
 /* Breakpoint stuff */
 struct bpt {
 	unsigned long	address;
-	unsigned int	*instr;
+	struct ppc_inst	*instr;
 	atomic_t	ref_count;
 	int		enabled;
 	unsigned long	pad;
@@ -117,7 +117,7 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
 
 #define BP_NUM(bp)	((bp) - bpts + 1)
 
-#define BPT_SIZE	(sizeof(unsigned int) * 2)
+#define BPT_SIZE	(sizeof(struct ppc_inst) * 2)
 #define BPT_WORDS	(BPT_SIZE / sizeof(unsigned int))
 extern unsigned int bpt_table[NBPTS * BPT_WORDS];
 
@@ -879,8 +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;
-			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
-			patch_instruction(bp->instr + 1, bpinstr);
+			bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
+			patch_instruction(bp->instr + 1, ppc_inst(bpinstr));
 			return bp;
 		}
 	}
@@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
 static void insert_bpts(void)
 {
 	int i;
-	unsigned int instr;
+	struct ppc_inst instr;
 	struct bpt *bp;
 
 	bp = bpts;
@@ -914,8 +914,8 @@ static void insert_bpts(void)
 		patch_instruction(bp->instr, instr);
 		if (bp->enabled & BP_CIABR)
 			continue;
-		if (patch_instruction((unsigned int *)bp->address,
-							bpinstr) != 0) {
+		if (patch_instruction((struct ppc_inst *)bp->address,
+							ppc_inst(bpinstr)) != 0) {
 			printf("Couldn't write instruction at %lx, "
 			       "disabling breakpoint there\n", bp->address);
 			bp->enabled &= ~BP_TRAP;
@@ -943,7 +943,7 @@ static void remove_bpts(void)
 {
 	int i;
 	struct bpt *bp;
-	unsigned instr;
+	struct 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
 		    && ppc_inst_equal(instr, ppc_inst(bpinstr))
 		    && patch_instruction(
-			(unsigned int *)bp->address, bp->instr[0]) != 0)
+			(struct 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;
+	struct 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;
+	struct ppc_inst instr;
 
 	addr &= ~3;
 	if (!is_kernel_addr(addr)) {
@@ -2846,7 +2846,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
 {
 	int nr, dotted;
 	unsigned long first_adr;
-	unsigned int inst, last_inst = ppc_inst(0);
+	struct ppc_inst inst, last_inst = ppc_inst(0);
 	unsigned char val[4];
 
 	dotted = 0;
-- 
2.17.1


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

* [PATCH v5 10/21] powerpc: Use a function for reading instructions
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (8 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 09/21] powerpc: Use a datatype for instructions Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07 10:42   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 11/21] powerpc: Define and use __get_user_instr{, inatomic}() Jordan Niethe
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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
v5: - Rename read_inst() -> probe_kernel_read_inst()
    - No longer modify uprobe probe type in this patch
---
 arch/powerpc/include/asm/inst.h    |  5 +++++
 arch/powerpc/kernel/kprobes.c      | 11 ++++------
 arch/powerpc/kernel/mce_power.c    |  2 +-
 arch/powerpc/kernel/optprobes.c    |  4 ++--
 arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++-----------
 arch/powerpc/lib/code-patching.c   | 23 ++++++++++-----------
 arch/powerpc/lib/feature-fixups.c  |  2 +-
 arch/powerpc/xmon/xmon.c           |  6 +++---
 8 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index a71decf5f871..369b35ce964c 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -27,6 +27,11 @@ static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
 	return ppc_inst(swab32(ppc_inst_val(x)));
 }
 
+static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
+{
+	return *ptr;
+}
+
 static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
 {
 	return !memcmp(&x, &y, sizeof(struct ppc_inst));
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 9ed996cb0589..ff53e5ef7e40 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
 int arch_prepare_kprobe(struct kprobe *p)
 {
 	int ret = 0;
-	struct ppc_inst insn = *(struct ppc_inst *)p->addr;
+	struct ppc_inst insn = ppc_inst_read((struct ppc_inst *)p->addr);
 
 	if ((unsigned long)p->addr & 0x03) {
 		printk("Attempt to register kprobe at an unaligned address\n");
@@ -125,11 +125,8 @@ int arch_prepare_kprobe(struct kprobe *p)
 	}
 
 	if (!ret) {
-		memcpy(p->ainsn.insn, p->addr,
-				MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
-		p->opcode = *p->addr;
-		flush_icache_range((unsigned long)p->ainsn.insn,
-			(unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t));
+		patch_instruction((struct ppc_inst *)p->ainsn.insn, insn);
+		p->opcode = ppc_inst_val(insn);
 	}
 
 	p->ainsn.boostable = 0;
@@ -217,7 +214,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
 static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
 {
 	int ret;
-	struct ppc_inst insn = *(struct ppc_inst *)p->ainsn.insn;
+	struct ppc_inst insn = ppc_inst_read((struct 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 7118b46a6543..859b602fa270 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 = *(struct ppc_inst *)(instr_addr);
+		instr = ppc_inst_read((struct 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 b61bbcee84f4..684640b8fa2e 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -100,8 +100,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(*(struct ppc_inst *)p->ainsn.insn) &&
-			analyse_instr(&op, &regs, *(struct ppc_inst *)p->ainsn.insn) == 1) {
+	if (!is_conditional_branch(ppc_inst_read((struct ppc_inst *)p->ainsn.insn)) &&
+			analyse_instr(&op, &regs, ppc_inst_read((struct ppc_inst *)p->ainsn.insn)) == 1) {
 		emulate_update_regs(&regs, &op);
 		nip = regs.nip;
 	}
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 442c62fb68ff..e78742613b36 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
+probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
+{
+	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
+}
+
 static struct ppc_inst
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
@@ -68,7 +74,7 @@ ftrace_modify_code(unsigned long ip, struct ppc_inst old, struct ppc_inst new)
 	 */
 
 	/* read the text we want to modify */
-	if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
+	if (probe_kernel_read_inst(&replaced, (void *)ip))
 		return -EFAULT;
 
 	/* Make sure it is what we expect it to be */
@@ -130,7 +136,7 @@ __ftrace_make_nop(struct module *mod,
 	struct ppc_inst op, pop;
 
 	/* read where this goes */
-	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
+	if (probe_kernel_read_inst(&op, (void *)ip)) {
 		pr_err("Fetching opcode failed.\n");
 		return -EFAULT;
 	}
@@ -164,7 +170,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 (probe_kernel_read_inst(&op, (void *)(ip - 4))) {
 		pr_err("Fetching instruction at %lx failed.\n", ip - 4);
 		return -EFAULT;
 	}
@@ -196,7 +202,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 (probe_kernel_read_inst(&op, (void *)(ip+4))) {
 		pr_err("Fetching op failed.\n");
 		return -EFAULT;
 	}
@@ -348,7 +354,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 (probe_kernel_read_inst(&op, (void *)tramp)) {
 		pr_debug("Fetching opcode failed.\n");
 		return -1;
 	}
@@ -398,7 +404,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 	struct ppc_inst op;
 
 	/* Read where this goes */
-	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
+	if (probe_kernel_read_inst(&op, (void *)ip)) {
 		pr_err("Fetching opcode failed.\n");
 		return -EFAULT;
 	}
@@ -524,7 +530,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 (probe_kernel_read_inst(op, ip))
+		return -EFAULT;
+
+	if (probe_kernel_read_inst(op + 1, ip + 4))
 		return -EFAULT;
 
 	if (!expected_nop_sequence(ip, op[0], op[1])) {
@@ -587,7 +596,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 (probe_kernel_read_inst(&op, (void *)ip))
 		return -EFAULT;
 
 	/* It should be pointing to a nop */
@@ -643,7 +652,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 (probe_kernel_read_inst(&op, ip)) {
 		pr_err("Unable to read ftrace location %p\n", ip);
 		return -EFAULT;
 	}
@@ -721,7 +730,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 (probe_kernel_read_inst(&op, (void *)ip)) {
 		pr_err("Fetching opcode failed.\n");
 		return -EFAULT;
 	}
@@ -846,7 +855,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 	struct ppc_inst old, new;
 	int ret;
 
-	old = *(struct ppc_inst *)&ftrace_call;
+	old = ppc_inst_read((struct ppc_inst *)&ftrace_call);
 	new = ftrace_call_replace(ip, (unsigned long)func, 1);
 	ret = ftrace_modify_code(ip, old, new);
 
@@ -854,7 +863,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 = *(struct ppc_inst *)&ftrace_regs_call;
+		old = ppc_inst_read((struct 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/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 91be4a0b51cb..ba08f3815d00 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -349,9 +349,9 @@ static unsigned long branch_bform_target(const struct ppc_inst *instr)
 
 unsigned long branch_target(const struct 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;
@@ -359,7 +359,7 @@ unsigned long branch_target(const struct ppc_inst *instr)
 
 int instr_is_branch_to_addr(const struct 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,13 +368,12 @@ int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long addr)
 int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest, const struct ppc_inst *src)
 {
 	unsigned long target;
-
 	target = branch_target(src);
 
-	if (instr_is_branch_iform(*src))
-		return create_branch(instr, dest, target, ppc_inst_val(*src));
-	else if (instr_is_branch_bform(*src))
-		return create_cond_branch(instr, dest, target, ppc_inst_val(*src));
+	if (instr_is_branch_iform(ppc_inst_read(src)))
+		return create_branch(instr, dest, target, ppc_inst_val(ppc_inst_read(src)));
+	else if (instr_is_branch_bform(ppc_inst_read(src)))
+		return create_cond_branch(instr, dest, target, ppc_inst_val(ppc_inst_read(src)));
 
 	return 1;
 }
@@ -598,7 +597,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(ppc_inst_equal(*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;
@@ -609,7 +608,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(ppc_inst_equal(*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;
@@ -655,7 +654,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(ppc_inst_equal(*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;
@@ -667,7 +666,7 @@ static void __init test_translate_branch(void)
 	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(p, addr));
 	check(instr_is_branch_to_addr(q, addr));
-	check(ppc_inst_equal(*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 8c5d0db77013..f00dd13b1c3c 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -48,7 +48,7 @@ static int patch_alt_instruction(struct ppc_inst *src, struct ppc_inst *dest,
 	int err;
 	struct ppc_inst instr;
 
-	instr = *src;
+	instr = ppc_inst_read(src);
 
 	if (instr_is_relative_branch(*src)) {
 		struct ppc_inst *target = (struct ppc_inst *)branch_target(src);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index e3d8e1b8ce01..5e3949322a6c 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -705,13 +705,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");
 			}
 		}
 	}
@@ -952,7 +952,7 @@ static void remove_bpts(void)
 		if (mread(bp->address, &instr, 4) == 4
 		    && ppc_inst_equal(instr, ppc_inst(bpinstr))
 		    && patch_instruction(
-			(struct ppc_inst *)bp->address, bp->instr[0]) != 0)
+			(struct 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] 71+ messages in thread

* [PATCH v5 11/21] powerpc: Define and use __get_user_instr{, inatomic}()
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (9 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 10/21] powerpc: Use a function for reading instructions Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07 10:48   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length Jordan Niethe
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Define specific __get_user_instr() and __get_user_instr_inatomic()
macros for reading instructions from user space.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/include/asm/uaccess.h  | 5 +++++
 arch/powerpc/kernel/align.c         | 2 +-
 arch/powerpc/kernel/hw_breakpoint.c | 2 +-
 arch/powerpc/kernel/vecemu.c        | 2 +-
 4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 2f500debae21..c0a35e4586a5 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -105,6 +105,11 @@ 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)))
 
+#define __get_user_instr(x, ptr) \
+	__get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
+
+#define __get_user_instr_inatomic(x, ptr) \
+	__get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
 extern long __put_user_bad(void);
 
 /*
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 66a6d1de7799..65cdfd41e3a1 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -304,7 +304,7 @@ int fix_alignment(struct pt_regs *regs)
 	 */
 	CHECK_FULL_REGS(regs);
 
-	if (unlikely(__get_user(instr.val, (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... */
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 542f65ccf68b..cebab14e2788 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.val, (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/vecemu.c b/arch/powerpc/kernel/vecemu.c
index bbf536e10902..c82ede46d71b 100644
--- a/arch/powerpc/kernel/vecemu.c
+++ b/arch/powerpc/kernel/vecemu.c
@@ -266,7 +266,7 @@ int emulate_altivec(struct pt_regs *regs)
 	unsigned int va, vb, vc, vd;
 	vector128 *vrs;
 
-	if (get_user(instr.val, (unsigned int __user *) regs->nip))
+	if (__get_user_instr(instr, (void __user *) regs->nip))
 		return -EFAULT;
 
 	word = ppc_inst_val(instr);
-- 
2.17.1


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

* [PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (10 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 11/21] powerpc: Define and use __get_user_instr{, inatomic}() Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07 11:14   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions Jordan Niethe
                   ` (9 subsequent siblings)
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Currently all instructions have the same length, but in preparation for
prefixed instructions introduce a function for returning instruction
length.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/include/asm/inst.h | 5 +++++
 arch/powerpc/kernel/kprobes.c   | 6 ++++--
 arch/powerpc/kernel/uprobes.c   | 2 +-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 369b35ce964c..70b37a35a91a 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -17,6 +17,11 @@ static inline u32 ppc_inst_val(struct ppc_inst x)
 	return x.val;
 }
 
+static inline bool ppc_inst_len(struct ppc_inst x)
+{
+	return sizeof(struct ppc_inst);
+}
+
 static inline int ppc_inst_opcode(struct ppc_inst x)
 {
 	return x.val >> 26;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index ff53e5ef7e40..8d17cfdcdc54 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -474,14 +474,16 @@ NOKPROBE_SYMBOL(trampoline_probe_handler);
  */
 int kprobe_post_handler(struct pt_regs *regs)
 {
+	int len;
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
 	if (!cur || user_mode(regs))
 		return 0;
 
+	len = ppc_inst_len(ppc_inst_read((struct ppc_inst *)cur->ainsn.insn));
 	/* make sure we got here for instruction we have a kprobe on */
-	if (((unsigned long)cur->ainsn.insn + 4) != regs->nip)
+	if (((unsigned long)cur->ainsn.insn + len) != regs->nip)
 		return 0;
 
 	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
@@ -490,7 +492,7 @@ int kprobe_post_handler(struct pt_regs *regs)
 	}
 
 	/* Adjust nip to after the single-stepped instruction */
-	regs->nip = (unsigned long)cur->addr + 4;
+	regs->nip = (unsigned long)cur->addr + len;
 	regs->msr |= kcb->kprobe_saved_msr;
 
 	/*Restore back the original saved kprobes variables and continue. */
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
index 31c870287f2b..8e63afa012ba 100644
--- a/arch/powerpc/kernel/uprobes.c
+++ b/arch/powerpc/kernel/uprobes.c
@@ -112,7 +112,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
 	 * support doesn't exist and have to fix-up the next instruction
 	 * to be executed.
 	 */
-	regs->nip = utask->vaddr + MAX_UINSN_BYTES;
+	regs->nip = utask->vaddr + ppc_inst_len(auprobe->insn);
 
 	user_disable_single_step(current);
 	return 0;
-- 
2.17.1


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

* [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (11 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-07 11:30   ` Balamuruhan S
  2020-04-06  8:09 ` [PATCH v5 14/21] powerpc/xmon: Move insertion of breakpoint for xol'ing Jordan Niethe
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

Currently in xmon, mread() is used for reading instructions. In
preparation for prefixed instructions, create and use a new function,
mread_instr(), especially for reading instructions.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
v5: New to series, seperated from "Add prefixed instructions to
instruction data type"
---
 arch/powerpc/xmon/xmon.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 5e3949322a6c..6f4cf01a58c1 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -125,6 +125,7 @@ extern unsigned int bpt_table[NBPTS * BPT_WORDS];
 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, struct ppc_inst *);
 static int handle_fault(struct pt_regs *);
 static void byterev(unsigned char *, int);
 static void memex(void);
@@ -899,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;
@@ -949,7 +950,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(
 			(struct ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0)
@@ -1165,7 +1166,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",
@@ -1332,7 +1333,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;
 	}
@@ -2125,6 +2126,21 @@ mwrite(unsigned long adrs, void *buf, int size)
 	return n;
 }
 
+static int
+mread_instr(unsigned long adrs, struct ppc_inst *instr)
+{
+	if (setjmp(bus_error_jmp) == 0) {
+		catch_memory_errors = 1;
+		sync();
+		*instr = ppc_inst_read((struct ppc_inst *)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] 71+ messages in thread

* [PATCH v5 14/21] powerpc/xmon: Move insertion of breakpoint for xol'ing
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (12 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 15/21] powerpc: Make test_translate_branch() independent of instruction length Jordan Niethe
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

When a new breakpoint is created, the second instruction of that
breakpoint is patched with a trap instruction. This assumes the length
of the instruction is always the same. In preparation for prefixed
instructions, remove this assumption. Insert the trap instruction at the
same time the first instruction is inserted.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/xmon/xmon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 6f4cf01a58c1..6f3bcdcfc9c7 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -881,7 +881,6 @@ static struct bpt *new_breakpoint(unsigned long a)
 		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
 			bp->address = a;
 			bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
-			patch_instruction(bp->instr + 1, ppc_inst(bpinstr));
 			return bp;
 		}
 	}
@@ -913,6 +912,7 @@ static void insert_bpts(void)
 			continue;
 		}
 		patch_instruction(bp->instr, instr);
+		patch_instruction((void *)bp->instr + ppc_inst_len(instr), ppc_inst(bpinstr));
 		if (bp->enabled & BP_CIABR)
 			continue;
 		if (patch_instruction((struct ppc_inst *)bp->address,
-- 
2.17.1


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

* [PATCH v5 15/21] powerpc: Make test_translate_branch() independent of instruction length
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (13 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 14/21] powerpc/xmon: Move insertion of breakpoint for xol'ing Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 16/21] powerpc: Enable Prefixed Instructions Jordan Niethe
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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 ba08f3815d00..c329ad657302 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -569,7 +569,7 @@ static void __init test_branch_bform(void)
 static void __init test_translate_branch(void)
 {
 	unsigned long addr;
-	struct ppc_inst *p, *q;
+	void *p, *q;
 	struct ppc_inst instr;
 	void *buf;
 
@@ -583,7 +583,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 = p + 4;
 	translate_branch(&instr, q, p);
 	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(q, addr));
@@ -639,7 +639,7 @@ static void __init test_translate_branch(void)
 	create_cond_branch(&instr, p, addr, 0);
 	patch_instruction(p, instr);
 	check(instr_is_branch_to_addr(p, addr));
-	q = p + 1;
+	q = buf + 4;
 	translate_branch(&instr, q, p);
 	patch_instruction(q, instr);
 	check(instr_is_branch_to_addr(q, addr));
-- 
2.17.1


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

* [PATCH v5 16/21] powerpc: Enable Prefixed Instructions
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (14 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 15/21] powerpc: Make test_translate_branch() independent of instruction length Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 17/21] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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.

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 related	[flat|nested] 71+ messages in thread

* [PATCH v5 17/21] powerpc: Define new SRR1 bits for a future ISA version
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (15 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 16/21] powerpc: Enable Prefixed Instructions Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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] 71+ messages in thread

* [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (16 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 17/21] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  9:52   ` Alistair Popple
                     ` (2 more replies)
  2020-04-06  8:09 ` [PATCH v5 19/21] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
                   ` (3 subsequent siblings)
  21 siblings, 3 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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
v5:  - Distinguish normal instructions from prefixed instructions with a
       0xff marker for the suffix.
     - __patch_instruction() using std for prefixed instructions
---
 arch/powerpc/include/asm/inst.h      | 71 ++++++++++++++++++++++++++--
 arch/powerpc/include/asm/kprobes.h   |  2 +-
 arch/powerpc/include/asm/uaccess.h   | 31 ++++++++++--
 arch/powerpc/include/asm/uprobes.h   |  2 +-
 arch/powerpc/kernel/optprobes.c      | 42 ++++++++--------
 arch/powerpc/kernel/optprobes_head.S |  3 ++
 arch/powerpc/kernel/trace/ftrace.c   | 26 +++++++++-
 arch/powerpc/lib/code-patching.c     | 19 +++++---
 arch/powerpc/lib/feature-fixups.c    |  5 +-
 arch/powerpc/lib/sstep.c             |  4 +-
 arch/powerpc/xmon/xmon.c             |  6 +--
 arch/powerpc/xmon/xmon_bpts.S        |  4 +-
 12 files changed, 171 insertions(+), 44 deletions(-)

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
index 70b37a35a91a..7e23e7146c66 100644
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -8,23 +8,67 @@
 
 struct ppc_inst {
         u32 val;
+#ifdef __powerpc64__
+        u32 suffix;
+#endif /* __powerpc64__ */
 } __packed;
 
-#define ppc_inst(x) ((struct ppc_inst){ .val = x })
+static inline int ppc_inst_opcode(struct ppc_inst x)
+{
+	return x.val >> 26;
+}
 
 static inline u32 ppc_inst_val(struct ppc_inst x)
 {
 	return x.val;
 }
 
-static inline bool ppc_inst_len(struct ppc_inst x)
+#ifdef __powerpc64__
+#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
+
+#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y) })
+
+static inline u32 ppc_inst_suffix(struct ppc_inst x)
 {
-	return sizeof(struct ppc_inst);
+	return x.suffix;
 }
 
-static inline int ppc_inst_opcode(struct ppc_inst x)
+static inline bool ppc_inst_prefixed(struct ppc_inst x) {
+	return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) != 0xff;
+}
+
+static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
 {
-	return x.val >> 26;
+	return ppc_inst_prefix(swab32(ppc_inst_val(x)),
+			       swab32(ppc_inst_suffix(x)));
+}
+
+static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
+{
+	u32 val, suffix = 0xff;
+	val = *(u32 *)ptr;
+	if ((val >> 26) == 1)
+		suffix = *((u32 *)ptr + 1);
+	return ppc_inst_prefix(val, suffix);
+}
+
+static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
+{
+	if (ppc_inst_prefixed(x)) {
+		*(u32 *)ptr = x.val;
+		*((u32 *)ptr + 1) = x.suffix;
+	} else {
+		*(u32 *)ptr = x.val;
+	}
+}
+
+#else
+
+#define ppc_inst(x) ((struct ppc_inst){ .val = x })
+
+static inline bool ppc_inst_prefixed(ppc_inst x)
+{
+	return 0;
 }
 
 static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
@@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
 	return ppc_inst(swab32(ppc_inst_val(x)));
 }
 
+static inline u32 ppc_inst_val(struct ppc_inst x)
+{
+	return x.val;
+}
+
 static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
 {
 	return *ptr;
 }
 
+static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
+{
+	*ptr = x;
+}
+
+#endif /* __powerpc64__ */
+
 static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
 {
 	return !memcmp(&x, &y, sizeof(struct ppc_inst));
 }
 
+static inline int ppc_inst_len(struct ppc_inst x)
+{
+	return (ppc_inst_prefixed(x)) ? 8  : 4;
+}
+
 #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/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index c0a35e4586a5..5a3f486ddf02 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -105,11 +105,34 @@ 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)))
 
-#define __get_user_instr(x, ptr) \
-	__get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
+#define __get_user_instr(x, ptr)			\
+({							\
+	long __gui_ret = 0;				\
+	unsigned int prefix, suffix;			\
+	__gui_ret = __get_user(prefix, (unsigned int __user *)ptr);		\
+	if (!__gui_ret && (prefix >> 26) == 1) {	\
+		__gui_ret = __get_user(suffix, (unsigned int __user *)ptr + 1);	\
+		(x) = ppc_inst_prefix(prefix, suffix);	\
+	} else {					\
+		(x) = ppc_inst(prefix);			\
+	}						\
+	__gui_ret;					\
+})
+
+#define __get_user_instr_inatomic(x, ptr)		\
+({							\
+	long __gui_ret = 0;				\
+	unsigned int prefix, suffix;			\
+	__gui_ret = __get_user_inatomic(prefix, (unsigned int __user *)ptr);		\
+	if (!__gui_ret && (prefix >> 26) == 1) {	\
+		__gui_ret = __get_user_inatomic(suffix, (unsigned int __user *)ptr + 1);	\
+		(x) = ppc_inst_prefix(prefix, suffix);	\
+	} else {					\
+		(x) = ppc_inst(prefix);			\
+	}						\
+	__gui_ret;					\
+})
 
-#define __get_user_instr_inatomic(x, ptr) \
-	__get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
 extern long __put_user_bad(void);
 
 /*
diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
index 7e3b329ba2d3..5bf65f5d44a9 100644
--- a/arch/powerpc/include/asm/uprobes.h
+++ b/arch/powerpc/include/asm/uprobes.h
@@ -15,7 +15,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/optprobes.c b/arch/powerpc/kernel/optprobes.c
index 684640b8fa2e..689daf430161 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -159,38 +159,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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS | ___PPC_RT(3) |
+	/* lis reg,(op)@highest */
+	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS | ___PPC_RT(reg) |
 			  ((val >> 48) & 0xffff)));
 	addr++;
 
-	/* ori r3,r3,(op)@higher */
-	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 32) & 0xffff)));
+	/* ori reg,reg,(op)@higher */
+	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(reg) |
+			  ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
 	addr++;
 
-	/* rldicr r3,r3,32,31 */
-	patch_instruction((struct ppc_inst *)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((struct ppc_inst *)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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 16) & 0xffff)));
+	/* oris reg,reg,(op)@h */
+	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS | ___PPC_RA(reg) |
+			  ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
 	addr++;
 
-	/* ori r3,r3,(op)@l */
-	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | (val & 0xffff)));
+	/* ori reg,reg,(op)@l */
+	patch_instruction((struct ppc_inst *)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)
 {
-	struct ppc_inst branch_op_callback, branch_emulate_step;
+	struct 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;
@@ -240,7 +240,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()
@@ -271,7 +271,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(*p->ainsn.insn, buff + TMPL_INSN_IDX);
+	temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
+	patch_imm64_load_insns(ppc_inst_val(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 e78742613b36..16041a5c86d5 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -41,11 +41,35 @@
 #define	NUM_FTRACE_TRAMPS	8
 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
 
+#ifdef __powerpc64__
 static long
 probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
 {
-	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
+	u32 val, suffix = 0;
+	long err;
+
+	err = probe_kernel_read((void *)&val,
+				src, sizeof(val));
+	if (err)
+		return err;
+
+	if ((val >> 26) == 1)
+		err = probe_kernel_read((void *)&suffix,
+					src + 4, MCOUNT_INSN_SIZE);
+	if (err)
+		return err;
+
+	*inst = ppc_inst_prefix(val, suffix);
+
+	return 0;
 }
+#else
+static long
+probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
+{
+	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE)
+}
+#endif
 
 static struct ppc_inst
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index c329ad657302..b4007e03d8fa 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -24,12 +24,19 @@ static int __patch_instruction(struct ppc_inst *exec_addr, struct ppc_inst instr
 {
 	int err = 0;
 
-	__put_user_asm(ppc_inst_val(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)) {
+		__put_user_asm(ppc_inst_val(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));
+	} else {
+		__put_user_asm((u64)ppc_inst_suffix(instr) << 32 | ppc_inst_val(instr), patch_addr, err, "std");
+		if (err)
+			return err;
+		asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
+								    "r" (exec_addr));
+	}
 
 	return 0;
 }
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index f00dd13b1c3c..5519cec83cc8 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -84,12 +84,13 @@ static int patch_feature_section(unsigned long value, struct fixup_entry *fcur)
 	src = alt_start;
 	dest = start;
 
-	for (; src < alt_end; src++, dest++) {
+	for (; src < alt_end; src = (void *)src + ppc_inst_len(ppc_inst_read(src)),
+	     (dest = (void *)dest + ppc_inst_len(ppc_inst_read(dest)))) {
 		if (patch_alt_instruction(src, dest, alt_start, alt_end))
 			return 1;
 	}
 
-	for (; dest < end; dest++)
+	for (; dest < end; dest = (void *)dest + ppc_inst_len(ppc_inst(PPC_INST_NOP)))
 		raw_patch_instruction(dest, ppc_inst(PPC_INST_NOP));
 
 	return 0;
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 52ddd3122dc8..8b285bf11218 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_val(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 6f3bcdcfc9c7..b704aebb099a 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -761,8 +761,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;
 	}
@@ -863,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
 	if (off >= sizeof(bpt_table))
 		return NULL;
 	*offp = off % BPT_SIZE;
-	if (*offp != 0 && *offp != 4)
+	if (*offp != 0 && *offp != 4 && *offp != 8)
 		return NULL;
 	return bpts + (off / BPT_SIZE);
 }
diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
index ebb2dbc70ca8..09058eb6abbd 100644
--- a/arch/powerpc/xmon/xmon_bpts.S
+++ b/arch/powerpc/xmon/xmon_bpts.S
@@ -3,6 +3,8 @@
 #include <asm/asm-compat.h>
 #include "xmon_bpts.h"
 
+/* Prefixed instructions can not cross 64 byte boundaries */
+.align 6
 .global bpt_table
 bpt_table:
-	.space NBPTS * 8
+	.space NBPTS * 16
-- 
2.17.1


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

* [PATCH v5 19/21] powerpc: Support prefixed instructions in alignment handler
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (17 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06  8:09 ` [PATCH v5 20/21] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: alistair, npiggin, bala24, Jordan Niethe, dja

If a prefixed instruction results in an alignment exception, the
SRR1_PREFIXED bit is set. The handler attempts to emulate the
responsible instruction and then increment the NIP past it. Use
SRR1_PREFIXED to determine by how much the NIP should be incremented.

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: Rolled into "Add prefixed instructions to instruction data type"
v5: Only one definition of inst_length()
---
 arch/powerpc/kernel/traps.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a4764b039749..9b97d2e6055a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -583,6 +583,8 @@ 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
 
 /* single-step stuff */
 #define single_stepping(regs)	(current->thread.debug.dbcr0 & DBCR0_IC)
@@ -597,12 +599,16 @@ 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 single_stepping(regs)	((regs)->msr & MSR_SE)
 #define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
 #define clear_br_trace(regs)	((regs)->msr &= ~MSR_BE)
 #endif
 
+#define inst_length(reason)	(((reason) & REASON_PREFIXED) ? 8 : 4)
+
 #if defined(CONFIG_E500)
 int machine_check_e500mc(struct pt_regs *regs)
 {
@@ -1593,11 +1599,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 +1621,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 +1635,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] 71+ messages in thread

* [PATCH v5 20/21] powerpc sstep: Add support for prefixed load/stores
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (18 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 19/21] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-06 11:29     ` kbuild test robot
  2020-04-06  8:09 ` [PATCH v5 21/21] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
  2020-04-09  6:39 ` [PATCH v5 00/21] Initial Prefixed Instruction support Christophe Leroy
  21 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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)

Reviewed-by: Balamuruhan S <bala24@linux.ibm.com>
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/include/asm/sstep.h |   4 +
 arch/powerpc/lib/sstep.c         | 159 +++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+)

diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index c3ce903ac488..9b200a5f8794 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/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 8b285bf11218..8b6aee0ee636 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,
 		  struct 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] 71+ messages in thread

* [PATCH v5 21/21] powerpc sstep: Add support for prefixed fixed-point arithmetic
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (19 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 20/21] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
@ 2020-04-06  8:09 ` Jordan Niethe
  2020-04-09  6:39 ` [PATCH v5 00/21] Initial Prefixed Instruction support Christophe Leroy
  21 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  8:09 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)

Reviewed-by: Balamuruhan S <bala24@linux.ibm.com>
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 8b6aee0ee636..eb24dbfc051a 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] 71+ messages in thread

* Re: [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code
  2020-04-06  8:09 ` [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code Jordan Niethe
@ 2020-04-06  8:22   ` Christophe Leroy
  2020-04-06  9:38     ` Jordan Niethe
  2020-04-07  7:04   ` Balamuruhan S
  2020-04-08 18:21   ` Segher Boessenkool
  2 siblings, 1 reply; 71+ messages in thread
From: Christophe Leroy @ 2020-04-06  8:22 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: bala24, alistair, dja, npiggin



Le 06/04/2020 à 10:09, Jordan Niethe a écrit :
> 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/include/asm/inst.h  | 5 +++++
>   arch/powerpc/kernel/align.c      | 2 +-
>   arch/powerpc/lib/code-patching.c | 4 ++--

What about store_updates_sp() in mm/fault.c ?

Christophe

>   3 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> index 5298ba33b6e5..93959016fe4b 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -8,4 +8,9 @@
>   
>   #define ppc_inst(x) (x)
>   
> +static inline int ppc_inst_opcode(u32 x)
> +{
> +	return x >> 26;
> +}
> +
>   #endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index 86e9bf62f18c..691013aa9f3c 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -314,7 +314,7 @@ int fix_alignment(struct pt_regs *regs)
>   	}
>   
>   #ifdef CONFIG_SPE
> -	if ((instr >> 26) == 0x4) {
> +	if (ppc_inst_opcode(instr) == 0x4) {
>   		int reg = (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 fdf0d6ea3575..099a515202aa 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -231,7 +231,7 @@ bool is_offset_in_branch_range(long offset)
>    */
>   bool is_conditional_branch(unsigned int instr)
>   {
> -	unsigned int opcode = instr >> 26;
> +	unsigned int opcode = ppc_inst_opcode(instr);
>   
>   	if (opcode == 16)       /* bc, bca, bcl, bcla */
>   		return true;
> @@ -289,7 +289,7 @@ int create_cond_branch(unsigned int *instr, const unsigned int *addr,
>   
>   static unsigned int branch_opcode(unsigned int instr)
>   {
> -	return (instr >> 26) & 0x3F;
> +	return ppc_inst_opcode(instr) & 0x3F;
>   }
>   
>   static int instr_is_branch_iform(unsigned int instr)
> 

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

* Re: [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code
  2020-04-06  8:22   ` Christophe Leroy
@ 2020-04-06  9:38     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06  9:38 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Alistair Popple, Nicholas Piggin, Balamuruhan S, linuxppc-dev,
	Daniel Axtens

On Mon, Apr 6, 2020 at 6:22 PM Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
>
>
> Le 06/04/2020 à 10:09, Jordan Niethe a écrit :
> > 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/include/asm/inst.h  | 5 +++++
> >   arch/powerpc/kernel/align.c      | 2 +-
> >   arch/powerpc/lib/code-patching.c | 4 ++--
>
> What about store_updates_sp() in mm/fault.c ?
True. An early revision of this series used analyse_instr() there,
which ended up causing issues. But it still can use the instruction
data type. I will change that.
>
> Christophe
>
> >   3 files changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
> > index 5298ba33b6e5..93959016fe4b 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -8,4 +8,9 @@
> >
> >   #define ppc_inst(x) (x)
> >
> > +static inline int ppc_inst_opcode(u32 x)
> > +{
> > +     return x >> 26;
> > +}
> > +
> >   #endif /* _ASM_INST_H */
> > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > index 86e9bf62f18c..691013aa9f3c 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -314,7 +314,7 @@ int fix_alignment(struct pt_regs *regs)
> >       }
> >
> >   #ifdef CONFIG_SPE
> > -     if ((instr >> 26) == 0x4) {
> > +     if (ppc_inst_opcode(instr) == 0x4) {
> >               int reg = (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 fdf0d6ea3575..099a515202aa 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -231,7 +231,7 @@ bool is_offset_in_branch_range(long offset)
> >    */
> >   bool is_conditional_branch(unsigned int instr)
> >   {
> > -     unsigned int opcode = instr >> 26;
> > +     unsigned int opcode = ppc_inst_opcode(instr);
> >
> >       if (opcode == 16)       /* bc, bca, bcl, bcla */
> >               return true;
> > @@ -289,7 +289,7 @@ int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> >
> >   static unsigned int branch_opcode(unsigned int instr)
> >   {
> > -     return (instr >> 26) & 0x3F;
> > +     return ppc_inst_opcode(instr) & 0x3F;
> >   }
> >
> >   static int instr_is_branch_iform(unsigned int instr)
> >

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06  8:09 ` [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
@ 2020-04-06  9:52   ` Alistair Popple
  2020-04-06 10:25     ` Christophe Leroy
  2020-04-06 10:42     ` Jordan Niethe
  2020-04-06 11:04     ` kbuild test robot
  2020-04-13 12:04   ` Balamuruhan S
  2 siblings, 2 replies; 71+ messages in thread
From: Alistair Popple @ 2020-04-06  9:52 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: npiggin, bala24, linuxppc-dev, dja

> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h index 70b37a35a91a..7e23e7146c66 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -8,23 +8,67 @@
> 
>  struct ppc_inst {
>          u32 val;
> +#ifdef __powerpc64__
> +        u32 suffix;
> +#endif /* __powerpc64__ */
>  } __packed;
> 
> -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> +static inline int ppc_inst_opcode(struct ppc_inst x)
> +{
> +	return x.val >> 26;
> +}
> 
>  static inline u32 ppc_inst_val(struct ppc_inst x)
>  {
>  	return x.val;
>  }
> 
> -static inline bool ppc_inst_len(struct ppc_inst x)
> +#ifdef __powerpc64__
> +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> +
> +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y)
> }) +
> +static inline u32 ppc_inst_suffix(struct ppc_inst x)
>  {
> -	return sizeof(struct ppc_inst);
> +	return x.suffix;
>  }
> 
> -static inline int ppc_inst_opcode(struct ppc_inst x)
> +static inline bool ppc_inst_prefixed(struct ppc_inst x) {
> +	return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) != 0xff;
> +}
> +
> +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
>  {
> -	return x.val >> 26;
> +	return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> +			       swab32(ppc_inst_suffix(x)));
> +}
> +
> +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> +{
> +	u32 val, suffix = 0xff;
> +	val = *(u32 *)ptr;
> +	if ((val >> 26) == 1)
> +		suffix = *((u32 *)ptr + 1);
> +	return ppc_inst_prefix(val, suffix);
> +}
> +
> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> +{
> +	if (ppc_inst_prefixed(x)) {
> +		*(u32 *)ptr = x.val;
> +		*((u32 *)ptr + 1) = x.suffix;
> +	} else {
> +		*(u32 *)ptr = x.val;
> +	}
> +}
> +
> +#else
> +
> +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> +
> +static inline bool ppc_inst_prefixed(ppc_inst x)
> +{
> +	return 0;
>  }
> 
>  static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> ppc_inst x) return ppc_inst(swab32(ppc_inst_val(x)));
>  }
> 
> +static inline u32 ppc_inst_val(struct ppc_inst x)
> +{
> +	return x.val;
> +}
> +
>  static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
>  {
>  	return *ptr;
>  }
> 
> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> +{
> +	*ptr = x;
> +}
> +
> +#endif /* __powerpc64__ */
> +
>  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
>  {
>  	return !memcmp(&x, &y, sizeof(struct ppc_inst));
>  }

Apologies for not picking this up earlier, I was hoping to get to the bottom 
of the issue I was seeing before you sent out v5. However the above definition 
of instruction equality does not seem correct because it does not consider the 
case when an instruction is not prefixed - a non-prefixed instruction should be 
considered equal if the first 32-bit opcode/value is the same. Something like:

	if (ppc_inst_prefixed(x) != ppc_inst_prefixed(y))
		return false;
	else if (ppc_inst_prefixed(x))
		return !memcmp(&x, &y, sizeof(struct ppc_inst));
	else
		return x.val == y.val;

This was causing failures in ftrace_modify_code() as it would falsely detect 
two non-prefixed instructions as being not equal due to differences in the suffix.
 
- Alistair

> +static inline int ppc_inst_len(struct ppc_inst x)
> +{
> +	return (ppc_inst_prefixed(x)) ? 8  : 4;
> +}
> +
>  #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/uaccess.h
> b/arch/powerpc/include/asm/uaccess.h index c0a35e4586a5..5a3f486ddf02
> 100644
> --- a/arch/powerpc/include/asm/uaccess.h
> +++ b/arch/powerpc/include/asm/uaccess.h
> @@ -105,11 +105,34 @@ 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)))
> 
> -#define __get_user_instr(x, ptr) \
> -	__get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> +#define __get_user_instr(x, ptr)			\
> +({							\
> +	long __gui_ret = 0;				\
> +	unsigned int prefix, suffix;			\
> +	__gui_ret = __get_user(prefix, (unsigned int __user *)ptr);		\
> +	if (!__gui_ret && (prefix >> 26) == 1) {	\
> +		__gui_ret = __get_user(suffix, (unsigned int __user *)ptr + 1);	\
> +		(x) = ppc_inst_prefix(prefix, suffix);	\
> +	} else {					\
> +		(x) = ppc_inst(prefix);			\
> +	}						\
> +	__gui_ret;					\
> +})
> +
> +#define __get_user_instr_inatomic(x, ptr)		\
> +({							\
> +	long __gui_ret = 0;				\
> +	unsigned int prefix, suffix;			\
> +	__gui_ret = __get_user_inatomic(prefix, (unsigned int __user *)ptr);		\
> +	if (!__gui_ret && (prefix >> 26) == 1) {	\
> +		__gui_ret = __get_user_inatomic(suffix, (unsigned int __user *)ptr +
> 1);	\ +		(x) = ppc_inst_prefix(prefix, suffix);	\
> +	} else {					\
> +		(x) = ppc_inst(prefix);			\
> +	}						\
> +	__gui_ret;					\
> +})
> 
> -#define __get_user_instr_inatomic(x, ptr) \
> -	__get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
>  extern long __put_user_bad(void);
> 
>  /*
> diff --git a/arch/powerpc/include/asm/uprobes.h
> b/arch/powerpc/include/asm/uprobes.h index 7e3b329ba2d3..5bf65f5d44a9
> 100644
> --- a/arch/powerpc/include/asm/uprobes.h
> +++ b/arch/powerpc/include/asm/uprobes.h
> @@ -15,7 +15,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/optprobes.c
> b/arch/powerpc/kernel/optprobes.c index 684640b8fa2e..689daf430161 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -159,38 +159,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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> ___PPC_RT(3) | +	/* lis reg,(op)@highest */
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> ___PPC_RT(reg) | ((val >> 48) & 0xffff)));
>  	addr++;
> 
> -	/* ori r3,r3,(op)@higher */
> -	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> ___PPC_RA(3) | -			  ___PPC_RS(3) | ((val >> 32) & 0xffff)));
> +	/* ori reg,reg,(op)@higher */
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> ___PPC_RA(reg) | +			  ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
>  	addr++;
> 
> -	/* rldicr r3,r3,32,31 */
> -	patch_instruction((struct ppc_inst *)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((struct ppc_inst *)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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> ___PPC_RA(3) | -			  ___PPC_RS(3) | ((val >> 16) & 0xffff)));
> +	/* oris reg,reg,(op)@h */
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> ___PPC_RA(reg) | +			  ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
>  	addr++;
> 
> -	/* ori r3,r3,(op)@l */
> -	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> ___PPC_RA(3) | -			  ___PPC_RS(3) | (val & 0xffff)));
> +	/* ori reg,reg,(op)@l */
> +	patch_instruction((struct ppc_inst *)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) {
> -	struct ppc_inst branch_op_callback, branch_emulate_step;
> +	struct 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;
> @@ -240,7 +240,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()
> @@ -271,7 +271,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(*p->ainsn.insn, buff + TMPL_INSN_IDX);
> +	temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> +	patch_imm64_load_insns(ppc_inst_val(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 e78742613b36..16041a5c86d5
> 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -41,11 +41,35 @@
>  #define	NUM_FTRACE_TRAMPS	8
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> 
> +#ifdef __powerpc64__
>  static long
>  probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
>  {
> -	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> +	u32 val, suffix = 0;
> +	long err;
> +
> +	err = probe_kernel_read((void *)&val,
> +				src, sizeof(val));
> +	if (err)
> +		return err;
> +
> +	if ((val >> 26) == 1)
> +		err = probe_kernel_read((void *)&suffix,
> +					src + 4, MCOUNT_INSN_SIZE);
> +	if (err)
> +		return err;
> +
> +	*inst = ppc_inst_prefix(val, suffix);
> +
> +	return 0;
>  }
> +#else
> +static long
> +probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> +{
> +	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE)
> +}
> +#endif
> 
>  static struct ppc_inst
>  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> diff --git a/arch/powerpc/lib/code-patching.c
> b/arch/powerpc/lib/code-patching.c index c329ad657302..b4007e03d8fa 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -24,12 +24,19 @@ static int __patch_instruction(struct ppc_inst
> *exec_addr, struct ppc_inst instr {
>  	int err = 0;
> 
> -	__put_user_asm(ppc_inst_val(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)) {
> +		__put_user_asm(ppc_inst_val(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));
> +	} else {
> +		__put_user_asm((u64)ppc_inst_suffix(instr) << 32 | ppc_inst_val(instr),
> patch_addr, err, "std"); +		if (err)
> +			return err;
> +		asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
> +								    "r" (exec_addr));
> +	}
> 
>  	return 0;
>  }
> diff --git a/arch/powerpc/lib/feature-fixups.c
> b/arch/powerpc/lib/feature-fixups.c index f00dd13b1c3c..5519cec83cc8 100644
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -84,12 +84,13 @@ static int patch_feature_section(unsigned long value,
> struct fixup_entry *fcur) src = alt_start;
>  	dest = start;
> 
> -	for (; src < alt_end; src++, dest++) {
> +	for (; src < alt_end; src = (void *)src +
> ppc_inst_len(ppc_inst_read(src)), +	     (dest = (void *)dest +
> ppc_inst_len(ppc_inst_read(dest)))) { if (patch_alt_instruction(src, dest,
> alt_start, alt_end))
>  			return 1;
>  	}
> 
> -	for (; dest < end; dest++)
> +	for (; dest < end; dest = (void *)dest +
> ppc_inst_len(ppc_inst(PPC_INST_NOP))) raw_patch_instruction(dest,
> ppc_inst(PPC_INST_NOP));
> 
>  	return 0;
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 52ddd3122dc8..8b285bf11218 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_val(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 6f3bcdcfc9c7..b704aebb099a 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -761,8 +761,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;
>  	}
> @@ -863,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long
> nip, unsigned long *offp) if (off >= sizeof(bpt_table))
>  		return NULL;
>  	*offp = off % BPT_SIZE;
> -	if (*offp != 0 && *offp != 4)
> +	if (*offp != 0 && *offp != 4 && *offp != 8)
>  		return NULL;
>  	return bpts + (off / BPT_SIZE);
>  }
> diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
> index ebb2dbc70ca8..09058eb6abbd 100644
> --- a/arch/powerpc/xmon/xmon_bpts.S
> +++ b/arch/powerpc/xmon/xmon_bpts.S
> @@ -3,6 +3,8 @@
>  #include <asm/asm-compat.h>
>  #include "xmon_bpts.h"
> 
> +/* Prefixed instructions can not cross 64 byte boundaries */
> +.align 6
>  .global bpt_table
>  bpt_table:
> -	.space NBPTS * 8
> +	.space NBPTS * 16





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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06  9:52   ` Alistair Popple
@ 2020-04-06 10:25     ` Christophe Leroy
  2020-04-06 11:13       ` Jordan Niethe
  2020-04-08 18:11       ` Segher Boessenkool
  2020-04-06 10:42     ` Jordan Niethe
  1 sibling, 2 replies; 71+ messages in thread
From: Christophe Leroy @ 2020-04-06 10:25 UTC (permalink / raw)
  To: Alistair Popple, Jordan Niethe; +Cc: bala24, linuxppc-dev, npiggin, dja



Le 06/04/2020 à 11:52, Alistair Popple a écrit :

[...]

>> @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
>> ppc_inst x) return ppc_inst(swab32(ppc_inst_val(x)));
>>   }
>>
>> +static inline u32 ppc_inst_val(struct ppc_inst x)
>> +{
>> +	return x.val;
>> +}
>> +
>>   static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
>>   {
>>   	return *ptr;
>>   }
>>
>> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
>> +{
>> +	*ptr = x;
>> +}
>> +
>> +#endif /* __powerpc64__ */
>> +
>>   static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
>>   {
>>   	return !memcmp(&x, &y, sizeof(struct ppc_inst));
>>   }
> 
> Apologies for not picking this up earlier, I was hoping to get to the bottom
> of the issue I was seeing before you sent out v5. However the above definition
> of instruction equality does not seem correct because it does not consider the
> case when an instruction is not prefixed - a non-prefixed instruction should be
> considered equal if the first 32-bit opcode/value is the same. Something like:
> 
> 	if (ppc_inst_prefixed(x) != ppc_inst_prefixed(y))
> 		return false;
> 	else if (ppc_inst_prefixed(x))
> 		return !memcmp(&x, &y, sizeof(struct ppc_inst));

Are we sure memcmp() is a good candidate for the comparison ? Can we do 
simpler ? Especially, I understood a prefixed instruction is a 64 bits 
properly aligned instruction, can we do a simple u64 compare ? Or is GCC 
intelligent enough to do that without calling memcmp() function which is 
heavy ?

> 	else
> 		return x.val == y.val;
> 
> This was causing failures in ftrace_modify_code() as it would falsely detect
> two non-prefixed instructions as being not equal due to differences in the suffix.
>   

Christophe

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

* Re: [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al.
  2020-04-06  8:09 ` [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al Jordan Niethe
@ 2020-04-06 10:25     ` kbuild test robot
  2020-04-07  6:10   ` Balamuruhan S
  1 sibling, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 10:25 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: kbuild-all, Jordan Niethe, npiggin, bala24, alistair, linuxppc-dev, dja

[-- Attachment #1: Type: text/plain, Size: 3282 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[also build test ERROR on next-20200406]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/powerpc/kernel/setup_32.c: In function 'machine_init':
>> arch/powerpc/kernel/setup_32.c:91:21: error: passing argument 1 of 'create_cond_branch' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                     ^~~~~
         |                     |
         |                     long unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:27:38: note: expected 'unsigned int *' but argument is of type 'long unsigned int *'
      27 | int create_cond_branch(unsigned int *instr, const unsigned int *addr,
         |                        ~~~~~~~~~~~~~~^~~~~
   cc1: all warnings being treated as errors

vim +/create_cond_branch +91 arch/powerpc/kernel/setup_32.c

    67	
    68	/*
    69	 * This is run before start_kernel(), the kernel has been relocated
    70	 * and we are running with enough of the MMU enabled to have our
    71	 * proper kernel virtual addresses
    72	 *
    73	 * We do the initial parsing of the flat device-tree and prepares
    74	 * for the MMU to be fully initialized.
    75	 */
    76	notrace void __init machine_init(u64 dt_ptr)
    77	{
    78		unsigned int *addr = (unsigned int *)patch_site_addr(&patch__memset_nocache);
    79		unsigned long insn;
    80	
    81		/* Configure static keys first, now that we're relocated. */
    82		setup_feature_keys();
    83	
    84		early_ioremap_setup();
    85	
    86		/* Enable early debugging if any specified (see udbg.h) */
    87		udbg_early_init();
    88	
    89		patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
    90	
  > 91		create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
    92		patch_instruction(addr, insn);	/* replace b by bne cr0 */
    93	
    94		/* Do some early initialization based on the flat device tree */
    95		early_init_devtree(__va(dt_ptr));
    96	
    97		early_init_mmu();
    98	
    99		setup_kdump_trampoline();
   100	}
   101	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al.
@ 2020-04-06 10:25     ` kbuild test robot
  0 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 10:25 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3363 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[also build test ERROR on next-20200406]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/powerpc/kernel/setup_32.c: In function 'machine_init':
>> arch/powerpc/kernel/setup_32.c:91:21: error: passing argument 1 of 'create_cond_branch' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                     ^~~~~
         |                     |
         |                     long unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:27:38: note: expected 'unsigned int *' but argument is of type 'long unsigned int *'
      27 | int create_cond_branch(unsigned int *instr, const unsigned int *addr,
         |                        ~~~~~~~~~~~~~~^~~~~
   cc1: all warnings being treated as errors

vim +/create_cond_branch +91 arch/powerpc/kernel/setup_32.c

    67	
    68	/*
    69	 * This is run before start_kernel(), the kernel has been relocated
    70	 * and we are running with enough of the MMU enabled to have our
    71	 * proper kernel virtual addresses
    72	 *
    73	 * We do the initial parsing of the flat device-tree and prepares
    74	 * for the MMU to be fully initialized.
    75	 */
    76	notrace void __init machine_init(u64 dt_ptr)
    77	{
    78		unsigned int *addr = (unsigned int *)patch_site_addr(&patch__memset_nocache);
    79		unsigned long insn;
    80	
    81		/* Configure static keys first, now that we're relocated. */
    82		setup_feature_keys();
    83	
    84		early_ioremap_setup();
    85	
    86		/* Enable early debugging if any specified (see udbg.h) */
    87		udbg_early_init();
    88	
    89		patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
    90	
  > 91		create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
    92		patch_instruction(addr, insn);	/* replace b by bne cr0 */
    93	
    94		/* Do some early initialization based on the flat device tree */
    95		early_init_devtree(__va(dt_ptr));
    96	
    97		early_init_mmu();
    98	
    99		setup_kdump_trampoline();
   100	}
   101	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 09/21] powerpc: Use a datatype for instructions
  2020-04-06  8:09 ` [PATCH v5 09/21] powerpc: Use a datatype for instructions Jordan Niethe
@ 2020-04-06 10:34     ` kbuild test robot
  2020-04-06 10:35     ` kbuild test robot
  2020-04-07 10:30   ` Balamuruhan S
  2 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 10:34 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: kbuild-all, Jordan Niethe, npiggin, bala24, alistair, linuxppc-dev, dja

[-- Attachment #1: Type: text/plain, Size: 3907 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-rhel-kconfig (attached as .config)
compiler: powerpc64le-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/powerpc/lib/feature-fixups.c: In function 'do_final_fixups':
>> arch/powerpc/lib/feature-fixups.c:404:25: error: passing argument 1 of 'raw_patch_instruction' from incompatible pointer type [-Werror=incompatible-pointer-types]
     404 |   raw_patch_instruction(dest, ppc_inst(*src));
         |                         ^~~~
         |                         |
         |                         int *
   In file included from arch/powerpc/lib/feature-fixups.c:18:
   arch/powerpc/include/asm/code-patching.h:32:44: note: expected 'struct ppc_inst *' but argument is of type 'int *'
      32 | int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
         |                           ~~~~~~~~~~~~~~~~~^~~~
   cc1: some warnings being treated as errors

vim +/raw_patch_instruction +404 arch/powerpc/lib/feature-fixups.c

2d1b2027626d51 Kumar Gala             2008-07-02  389  
9402c684613163 Benjamin Herrenschmidt 2016-07-05  390  static void do_final_fixups(void)
d715e433b7ad19 Anton Blanchard        2011-11-14  391  {
d715e433b7ad19 Anton Blanchard        2011-11-14  392  #if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
d715e433b7ad19 Anton Blanchard        2011-11-14  393  	int *src, *dest;
d715e433b7ad19 Anton Blanchard        2011-11-14  394  	unsigned long length;
d715e433b7ad19 Anton Blanchard        2011-11-14  395  
d715e433b7ad19 Anton Blanchard        2011-11-14  396  	if (PHYSICAL_START == 0)
d715e433b7ad19 Anton Blanchard        2011-11-14  397  		return;
d715e433b7ad19 Anton Blanchard        2011-11-14  398  
d715e433b7ad19 Anton Blanchard        2011-11-14  399  	src = (int *)(KERNELBASE + PHYSICAL_START);
d715e433b7ad19 Anton Blanchard        2011-11-14  400  	dest = (int *)KERNELBASE;
d715e433b7ad19 Anton Blanchard        2011-11-14  401  	length = (__end_interrupts - _stext) / sizeof(int);
d715e433b7ad19 Anton Blanchard        2011-11-14  402  
d715e433b7ad19 Anton Blanchard        2011-11-14  403  	while (length--) {
16f7ae823ee707 Jordan Niethe          2020-04-06 @404  		raw_patch_instruction(dest, ppc_inst(*src));
d715e433b7ad19 Anton Blanchard        2011-11-14  405  		src++;
d715e433b7ad19 Anton Blanchard        2011-11-14  406  		dest++;
d715e433b7ad19 Anton Blanchard        2011-11-14  407  	}
d715e433b7ad19 Anton Blanchard        2011-11-14  408  #endif
d715e433b7ad19 Anton Blanchard        2011-11-14  409  }
d715e433b7ad19 Anton Blanchard        2011-11-14  410  

:::::: The code at line 404 was first introduced by commit
:::::: 16f7ae823ee70796c5ba2cc321b2c02f3dcfb816 powerpc: Use a macro for creating instructions from u32s

:::::: TO: Jordan Niethe <jniethe5@gmail.com>
:::::: CC: 0day robot <lkp@intel.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 15331 bytes --]

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

* Re: [PATCH v5 09/21] powerpc: Use a datatype for instructions
@ 2020-04-06 10:34     ` kbuild test robot
  0 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 10:34 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3980 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-rhel-kconfig (attached as .config)
compiler: powerpc64le-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/powerpc/lib/feature-fixups.c: In function 'do_final_fixups':
>> arch/powerpc/lib/feature-fixups.c:404:25: error: passing argument 1 of 'raw_patch_instruction' from incompatible pointer type [-Werror=incompatible-pointer-types]
     404 |   raw_patch_instruction(dest, ppc_inst(*src));
         |                         ^~~~
         |                         |
         |                         int *
   In file included from arch/powerpc/lib/feature-fixups.c:18:
   arch/powerpc/include/asm/code-patching.h:32:44: note: expected 'struct ppc_inst *' but argument is of type 'int *'
      32 | int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
         |                           ~~~~~~~~~~~~~~~~~^~~~
   cc1: some warnings being treated as errors

vim +/raw_patch_instruction +404 arch/powerpc/lib/feature-fixups.c

2d1b2027626d51 Kumar Gala             2008-07-02  389  
9402c684613163 Benjamin Herrenschmidt 2016-07-05  390  static void do_final_fixups(void)
d715e433b7ad19 Anton Blanchard        2011-11-14  391  {
d715e433b7ad19 Anton Blanchard        2011-11-14  392  #if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
d715e433b7ad19 Anton Blanchard        2011-11-14  393  	int *src, *dest;
d715e433b7ad19 Anton Blanchard        2011-11-14  394  	unsigned long length;
d715e433b7ad19 Anton Blanchard        2011-11-14  395  
d715e433b7ad19 Anton Blanchard        2011-11-14  396  	if (PHYSICAL_START == 0)
d715e433b7ad19 Anton Blanchard        2011-11-14  397  		return;
d715e433b7ad19 Anton Blanchard        2011-11-14  398  
d715e433b7ad19 Anton Blanchard        2011-11-14  399  	src = (int *)(KERNELBASE + PHYSICAL_START);
d715e433b7ad19 Anton Blanchard        2011-11-14  400  	dest = (int *)KERNELBASE;
d715e433b7ad19 Anton Blanchard        2011-11-14  401  	length = (__end_interrupts - _stext) / sizeof(int);
d715e433b7ad19 Anton Blanchard        2011-11-14  402  
d715e433b7ad19 Anton Blanchard        2011-11-14  403  	while (length--) {
16f7ae823ee707 Jordan Niethe          2020-04-06 @404  		raw_patch_instruction(dest, ppc_inst(*src));
d715e433b7ad19 Anton Blanchard        2011-11-14  405  		src++;
d715e433b7ad19 Anton Blanchard        2011-11-14  406  		dest++;
d715e433b7ad19 Anton Blanchard        2011-11-14  407  	}
d715e433b7ad19 Anton Blanchard        2011-11-14  408  #endif
d715e433b7ad19 Anton Blanchard        2011-11-14  409  }
d715e433b7ad19 Anton Blanchard        2011-11-14  410  

:::::: The code at line 404 was first introduced by commit
:::::: 16f7ae823ee70796c5ba2cc321b2c02f3dcfb816 powerpc: Use a macro for creating instructions from u32s

:::::: TO: Jordan Niethe <jniethe5@gmail.com>
:::::: CC: 0day robot <lkp@intel.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 15331 bytes --]

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

* Re: [PATCH v5 09/21] powerpc: Use a datatype for instructions
  2020-04-06  8:09 ` [PATCH v5 09/21] powerpc: Use a datatype for instructions Jordan Niethe
@ 2020-04-06 10:35     ` kbuild test robot
  2020-04-06 10:35     ` kbuild test robot
  2020-04-07 10:30   ` Balamuruhan S
  2 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 10:35 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: kbuild-all, Jordan Niethe, npiggin, bala24, alistair, linuxppc-dev, dja

[-- Attachment #1: Type: text/plain, Size: 11038 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from arch/powerpc/include/asm/asm-compat.h:6,
                    from arch/powerpc/include/asm/bitops.h:42,
                    from include/linux/bitops.h:29,
                    from include/linux/kernel.h:12,
                    from include/linux/list.h:9,
                    from include/linux/module.h:12,
                    from arch/powerpc/kernel/setup_32.c:6:
   arch/powerpc/kernel/setup_32.c: In function 'machine_init':
>> arch/powerpc/include/asm/ppc-opcode.h:234:24: error: incompatible type for argument 2 of 'patch_instruction_site'
     234 | #define PPC_INST_NOP   0x60000000
         |                        ^~~~~~~~~~
         |                        |
         |                        int
>> arch/powerpc/kernel/setup_32.c:89:49: note: in expansion of macro 'PPC_INST_NOP'
      89 |  patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
         |                                                 ^~~~~~~~~~~~
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:39:69: note: expected 'struct ppc_inst' but argument is of type 'int'
      39 | static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
         |                                                     ~~~~~~~~~~~~~~~~^~~~~
>> arch/powerpc/kernel/setup_32.c:91:48: error: passing argument 1 of 'branch_target' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                                                ^~~~
         |                                                |
         |                                                unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:63:52: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      63 | unsigned long branch_target(const struct ppc_inst *instr);
         |                             ~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   arch/powerpc/kernel/setup_32.c:91:28: error: passing argument 2 of 'create_cond_branch' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                            ^~~~
         |                            |
         |                            unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:28:71: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      28 | int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
         |                                                ~~~~~~~~~~~~~~~~~~~~~~~^~~~
>> arch/powerpc/kernel/setup_32.c:92:20: error: passing argument 1 of 'patch_instruction' from incompatible pointer type [-Werror=incompatible-pointer-types]
      92 |  patch_instruction(addr, insn); /* replace b by bne cr0 */
         |                    ^~~~
         |                    |
         |                    unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:31:40: note: expected 'struct ppc_inst *' but argument is of type 'unsigned int *'
      31 | int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
         |                       ~~~~~~~~~~~~~~~~~^~~~
   cc1: all warnings being treated as errors

vim +/patch_instruction_site +234 arch/powerpc/include/asm/ppc-opcode.h

9123c5ed45a583 Hongtao Jia          2013-04-28  193  
16c57b3620d77e Kumar Gala           2009-02-10  194  /* sorted alphabetically */
95213959aefc94 Anshuman Khandual    2013-04-22  195  #define PPC_INST_BHRBE			0x7c00025c
95213959aefc94 Anshuman Khandual    2013-04-22  196  #define PPC_INST_CLRBHRB		0x7c00035c
07d2a628bc0008 Nicholas Piggin      2017-06-09  197  #define PPC_INST_COPY			0x7c20060c
8a649045e75a4b Chris Smart          2016-04-26  198  #define PPC_INST_CP_ABORT		0x7c00068c
e66ca3db5917f4 Matt Brown           2017-08-04  199  #define PPC_INST_DARN			0x7c0005e6
16c57b3620d77e Kumar Gala           2009-02-10  200  #define PPC_INST_DCBA			0x7c0005ec
16c57b3620d77e Kumar Gala           2009-02-10  201  #define PPC_INST_DCBA_MASK		0xfc0007fe
16c57b3620d77e Kumar Gala           2009-02-10  202  #define PPC_INST_DCBAL			0x7c2005ec
16c57b3620d77e Kumar Gala           2009-02-10  203  #define PPC_INST_DCBZL			0x7c2007ec
1afc149def25ac Tony Breeds          2012-10-02  204  #define PPC_INST_ICBT			0x7c00002c
edc424f8cd84bb Dan Streetman        2015-05-07  205  #define PPC_INST_ICSWX			0x7c00032d
edc424f8cd84bb Dan Streetman        2015-05-07  206  #define PPC_INST_ICSWEPX		0x7c00076d
16c57b3620d77e Kumar Gala           2009-02-10  207  #define PPC_INST_ISEL			0x7c00001e
16c57b3620d77e Kumar Gala           2009-02-10  208  #define PPC_INST_ISEL_MASK		0xfc00003e
864b9e6fd76489 Anton Blanchard      2010-02-10  209  #define PPC_INST_LDARX			0x7c0000a8
156d0e290e969c Naveen N. Rao        2016-06-22  210  #define PPC_INST_STDCX			0x7c0001ad
350779a29f11f8 Paul Mackerras       2017-08-30  211  #define PPC_INST_LQARX			0x7c000228
350779a29f11f8 Paul Mackerras       2017-08-30  212  #define PPC_INST_STQCX			0x7c00016d
16c57b3620d77e Kumar Gala           2009-02-10  213  #define PPC_INST_LSWI			0x7c0004aa
16c57b3620d77e Kumar Gala           2009-02-10  214  #define PPC_INST_LSWX			0x7c00042a
d6ccb1f55ddf51 Kumar Gala           2010-03-10  215  #define PPC_INST_LWARX			0x7c000028
156d0e290e969c Naveen N. Rao        2016-06-22  216  #define PPC_INST_STWCX			0x7c00012d
16c57b3620d77e Kumar Gala           2009-02-10  217  #define PPC_INST_LWSYNC			0x7c2004ac
9863c28a2af90a James Yang           2013-07-03  218  #define PPC_INST_SYNC			0x7c0004ac
9863c28a2af90a James Yang           2013-07-03  219  #define PPC_INST_SYNC_MASK		0xfc0007fe
ddc6cd0d70a6f9 Christophe Leroy     2016-05-17  220  #define PPC_INST_ISYNC			0x4c00012c
dfb432cb960bfc Michael Neuling      2009-04-29  221  #define PPC_INST_LXVD2X			0x7c000698
16c57b3620d77e Kumar Gala           2009-02-10  222  #define PPC_INST_MCRXR			0x7c000400
16c57b3620d77e Kumar Gala           2009-02-10  223  #define PPC_INST_MCRXR_MASK		0xfc0007fe
16c57b3620d77e Kumar Gala           2009-02-10  224  #define PPC_INST_MFSPR_PVR		0x7c1f42a6
178f358208ceb8 Anton Blanchard      2017-01-19  225  #define PPC_INST_MFSPR_PVR_MASK		0xfc1ffffe
e16c8765533a15 Andy Fleming         2011-12-08  226  #define PPC_INST_MFTMR			0x7c0002dc
16c57b3620d77e Kumar Gala           2009-02-10  227  #define PPC_INST_MSGSND			0x7c00019c
755563bc79c764 Paul Mackerras       2015-03-19  228  #define PPC_INST_MSGCLR			0x7c0001dc
6b3edefefa6752 Nicholas Piggin      2017-04-13  229  #define PPC_INST_MSGSYNC		0x7c0006ec
42d02b81f265b7 Ian Munsie           2012-11-14  230  #define PPC_INST_MSGSNDP		0x7c00011c
a9af97aa0a12c3 Nicholas Piggin      2017-06-13  231  #define PPC_INST_MSGCLRP		0x7c00015c
4bb3c7a0208fc1 Paul Mackerras       2018-03-21  232  #define PPC_INST_MTMSRD			0x7c000164
e16c8765533a15 Andy Fleming         2011-12-08  233  #define PPC_INST_MTTMR			0x7c0003dc
16c57b3620d77e Kumar Gala           2009-02-10 @234  #define PPC_INST_NOP			0x60000000
07d2a628bc0008 Nicholas Piggin      2017-06-09  235  #define PPC_INST_PASTE			0x7c20070d
16c57b3620d77e Kumar Gala           2009-02-10  236  #define PPC_INST_POPCNTB		0x7c0000f4
16c57b3620d77e Kumar Gala           2009-02-10  237  #define PPC_INST_POPCNTB_MASK		0xfc0007fe
b5f9b6665b70b4 Anton Blanchard      2010-12-07  238  #define PPC_INST_POPCNTD		0x7c0003f4
b5f9b6665b70b4 Anton Blanchard      2010-12-07  239  #define PPC_INST_POPCNTW		0x7c0002f4
4bb3c7a0208fc1 Paul Mackerras       2018-03-21  240  #define PPC_INST_RFEBB			0x4c000124
16c57b3620d77e Kumar Gala           2009-02-10  241  #define PPC_INST_RFCI			0x4c000066
16c57b3620d77e Kumar Gala           2009-02-10  242  #define PPC_INST_RFDI			0x4c00004e
4bb3c7a0208fc1 Paul Mackerras       2018-03-21  243  #define PPC_INST_RFID			0x4c000024
16c57b3620d77e Kumar Gala           2009-02-10  244  #define PPC_INST_RFMCI			0x4c00004c
cd99ddbea250ee Christophe Leroy     2018-01-12  245  #define PPC_INST_MFSPR			0x7c0002a6
efcac6589a277c Alexey Kardashevskiy 2011-03-02  246  #define PPC_INST_MFSPR_DSCR		0x7c1102a6
178f358208ceb8 Anton Blanchard      2017-01-19  247  #define PPC_INST_MFSPR_DSCR_MASK	0xfc1ffffe
efcac6589a277c Alexey Kardashevskiy 2011-03-02  248  #define PPC_INST_MTSPR_DSCR		0x7c1103a6
178f358208ceb8 Anton Blanchard      2017-01-19  249  #define PPC_INST_MTSPR_DSCR_MASK	0xfc1ffffe
73d2fb758e678c Anton Blanchard      2013-05-01  250  #define PPC_INST_MFSPR_DSCR_USER	0x7c0302a6
178f358208ceb8 Anton Blanchard      2017-01-19  251  #define PPC_INST_MFSPR_DSCR_USER_MASK	0xfc1ffffe
73d2fb758e678c Anton Blanchard      2013-05-01  252  #define PPC_INST_MTSPR_DSCR_USER	0x7c0303a6
178f358208ceb8 Anton Blanchard      2017-01-19  253  #define PPC_INST_MTSPR_DSCR_USER_MASK	0xfc1ffffe
6dd7a82cc54ebd Anton Blanchard      2016-07-01  254  #define PPC_INST_MFVSRD			0x7c000066
6dd7a82cc54ebd Anton Blanchard      2016-07-01  255  #define PPC_INST_MTVSRD			0x7c000166
d16952a629129c Christophe Leroy     2018-11-09  256  #define PPC_INST_SC			0x44000002
697d3899dcb4bc Paul Mackerras       2011-12-12  257  #define PPC_INST_SLBFEE			0x7c0007a7
09cf5bcb0c9355 Aneesh Kumar K.V     2016-07-13  258  #define PPC_INST_SLBIA			0x7c0003e4
16c57b3620d77e Kumar Gala           2009-02-10  259  

:::::: The code at line 234 was first introduced by commit
:::::: 16c57b3620d77e0bc981da5ef32beae730512684 powerpc: Unify opcode definitions and support

:::::: TO: Kumar Gala <galak@kernel.crashing.org>
:::::: CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 09/21] powerpc: Use a datatype for instructions
@ 2020-04-06 10:35     ` kbuild test robot
  0 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 10:35 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 11193 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from arch/powerpc/include/asm/asm-compat.h:6,
                    from arch/powerpc/include/asm/bitops.h:42,
                    from include/linux/bitops.h:29,
                    from include/linux/kernel.h:12,
                    from include/linux/list.h:9,
                    from include/linux/module.h:12,
                    from arch/powerpc/kernel/setup_32.c:6:
   arch/powerpc/kernel/setup_32.c: In function 'machine_init':
>> arch/powerpc/include/asm/ppc-opcode.h:234:24: error: incompatible type for argument 2 of 'patch_instruction_site'
     234 | #define PPC_INST_NOP   0x60000000
         |                        ^~~~~~~~~~
         |                        |
         |                        int
>> arch/powerpc/kernel/setup_32.c:89:49: note: in expansion of macro 'PPC_INST_NOP'
      89 |  patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
         |                                                 ^~~~~~~~~~~~
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:39:69: note: expected 'struct ppc_inst' but argument is of type 'int'
      39 | static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
         |                                                     ~~~~~~~~~~~~~~~~^~~~~
>> arch/powerpc/kernel/setup_32.c:91:48: error: passing argument 1 of 'branch_target' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                                                ^~~~
         |                                                |
         |                                                unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:63:52: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      63 | unsigned long branch_target(const struct ppc_inst *instr);
         |                             ~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   arch/powerpc/kernel/setup_32.c:91:28: error: passing argument 2 of 'create_cond_branch' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                            ^~~~
         |                            |
         |                            unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:28:71: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      28 | int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
         |                                                ~~~~~~~~~~~~~~~~~~~~~~~^~~~
>> arch/powerpc/kernel/setup_32.c:92:20: error: passing argument 1 of 'patch_instruction' from incompatible pointer type [-Werror=incompatible-pointer-types]
      92 |  patch_instruction(addr, insn); /* replace b by bne cr0 */
         |                    ^~~~
         |                    |
         |                    unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:31:40: note: expected 'struct ppc_inst *' but argument is of type 'unsigned int *'
      31 | int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
         |                       ~~~~~~~~~~~~~~~~~^~~~
   cc1: all warnings being treated as errors

vim +/patch_instruction_site +234 arch/powerpc/include/asm/ppc-opcode.h

9123c5ed45a583 Hongtao Jia          2013-04-28  193  
16c57b3620d77e Kumar Gala           2009-02-10  194  /* sorted alphabetically */
95213959aefc94 Anshuman Khandual    2013-04-22  195  #define PPC_INST_BHRBE			0x7c00025c
95213959aefc94 Anshuman Khandual    2013-04-22  196  #define PPC_INST_CLRBHRB		0x7c00035c
07d2a628bc0008 Nicholas Piggin      2017-06-09  197  #define PPC_INST_COPY			0x7c20060c
8a649045e75a4b Chris Smart          2016-04-26  198  #define PPC_INST_CP_ABORT		0x7c00068c
e66ca3db5917f4 Matt Brown           2017-08-04  199  #define PPC_INST_DARN			0x7c0005e6
16c57b3620d77e Kumar Gala           2009-02-10  200  #define PPC_INST_DCBA			0x7c0005ec
16c57b3620d77e Kumar Gala           2009-02-10  201  #define PPC_INST_DCBA_MASK		0xfc0007fe
16c57b3620d77e Kumar Gala           2009-02-10  202  #define PPC_INST_DCBAL			0x7c2005ec
16c57b3620d77e Kumar Gala           2009-02-10  203  #define PPC_INST_DCBZL			0x7c2007ec
1afc149def25ac Tony Breeds          2012-10-02  204  #define PPC_INST_ICBT			0x7c00002c
edc424f8cd84bb Dan Streetman        2015-05-07  205  #define PPC_INST_ICSWX			0x7c00032d
edc424f8cd84bb Dan Streetman        2015-05-07  206  #define PPC_INST_ICSWEPX		0x7c00076d
16c57b3620d77e Kumar Gala           2009-02-10  207  #define PPC_INST_ISEL			0x7c00001e
16c57b3620d77e Kumar Gala           2009-02-10  208  #define PPC_INST_ISEL_MASK		0xfc00003e
864b9e6fd76489 Anton Blanchard      2010-02-10  209  #define PPC_INST_LDARX			0x7c0000a8
156d0e290e969c Naveen N. Rao        2016-06-22  210  #define PPC_INST_STDCX			0x7c0001ad
350779a29f11f8 Paul Mackerras       2017-08-30  211  #define PPC_INST_LQARX			0x7c000228
350779a29f11f8 Paul Mackerras       2017-08-30  212  #define PPC_INST_STQCX			0x7c00016d
16c57b3620d77e Kumar Gala           2009-02-10  213  #define PPC_INST_LSWI			0x7c0004aa
16c57b3620d77e Kumar Gala           2009-02-10  214  #define PPC_INST_LSWX			0x7c00042a
d6ccb1f55ddf51 Kumar Gala           2010-03-10  215  #define PPC_INST_LWARX			0x7c000028
156d0e290e969c Naveen N. Rao        2016-06-22  216  #define PPC_INST_STWCX			0x7c00012d
16c57b3620d77e Kumar Gala           2009-02-10  217  #define PPC_INST_LWSYNC			0x7c2004ac
9863c28a2af90a James Yang           2013-07-03  218  #define PPC_INST_SYNC			0x7c0004ac
9863c28a2af90a James Yang           2013-07-03  219  #define PPC_INST_SYNC_MASK		0xfc0007fe
ddc6cd0d70a6f9 Christophe Leroy     2016-05-17  220  #define PPC_INST_ISYNC			0x4c00012c
dfb432cb960bfc Michael Neuling      2009-04-29  221  #define PPC_INST_LXVD2X			0x7c000698
16c57b3620d77e Kumar Gala           2009-02-10  222  #define PPC_INST_MCRXR			0x7c000400
16c57b3620d77e Kumar Gala           2009-02-10  223  #define PPC_INST_MCRXR_MASK		0xfc0007fe
16c57b3620d77e Kumar Gala           2009-02-10  224  #define PPC_INST_MFSPR_PVR		0x7c1f42a6
178f358208ceb8 Anton Blanchard      2017-01-19  225  #define PPC_INST_MFSPR_PVR_MASK		0xfc1ffffe
e16c8765533a15 Andy Fleming         2011-12-08  226  #define PPC_INST_MFTMR			0x7c0002dc
16c57b3620d77e Kumar Gala           2009-02-10  227  #define PPC_INST_MSGSND			0x7c00019c
755563bc79c764 Paul Mackerras       2015-03-19  228  #define PPC_INST_MSGCLR			0x7c0001dc
6b3edefefa6752 Nicholas Piggin      2017-04-13  229  #define PPC_INST_MSGSYNC		0x7c0006ec
42d02b81f265b7 Ian Munsie           2012-11-14  230  #define PPC_INST_MSGSNDP		0x7c00011c
a9af97aa0a12c3 Nicholas Piggin      2017-06-13  231  #define PPC_INST_MSGCLRP		0x7c00015c
4bb3c7a0208fc1 Paul Mackerras       2018-03-21  232  #define PPC_INST_MTMSRD			0x7c000164
e16c8765533a15 Andy Fleming         2011-12-08  233  #define PPC_INST_MTTMR			0x7c0003dc
16c57b3620d77e Kumar Gala           2009-02-10 @234  #define PPC_INST_NOP			0x60000000
07d2a628bc0008 Nicholas Piggin      2017-06-09  235  #define PPC_INST_PASTE			0x7c20070d
16c57b3620d77e Kumar Gala           2009-02-10  236  #define PPC_INST_POPCNTB		0x7c0000f4
16c57b3620d77e Kumar Gala           2009-02-10  237  #define PPC_INST_POPCNTB_MASK		0xfc0007fe
b5f9b6665b70b4 Anton Blanchard      2010-12-07  238  #define PPC_INST_POPCNTD		0x7c0003f4
b5f9b6665b70b4 Anton Blanchard      2010-12-07  239  #define PPC_INST_POPCNTW		0x7c0002f4
4bb3c7a0208fc1 Paul Mackerras       2018-03-21  240  #define PPC_INST_RFEBB			0x4c000124
16c57b3620d77e Kumar Gala           2009-02-10  241  #define PPC_INST_RFCI			0x4c000066
16c57b3620d77e Kumar Gala           2009-02-10  242  #define PPC_INST_RFDI			0x4c00004e
4bb3c7a0208fc1 Paul Mackerras       2018-03-21  243  #define PPC_INST_RFID			0x4c000024
16c57b3620d77e Kumar Gala           2009-02-10  244  #define PPC_INST_RFMCI			0x4c00004c
cd99ddbea250ee Christophe Leroy     2018-01-12  245  #define PPC_INST_MFSPR			0x7c0002a6
efcac6589a277c Alexey Kardashevskiy 2011-03-02  246  #define PPC_INST_MFSPR_DSCR		0x7c1102a6
178f358208ceb8 Anton Blanchard      2017-01-19  247  #define PPC_INST_MFSPR_DSCR_MASK	0xfc1ffffe
efcac6589a277c Alexey Kardashevskiy 2011-03-02  248  #define PPC_INST_MTSPR_DSCR		0x7c1103a6
178f358208ceb8 Anton Blanchard      2017-01-19  249  #define PPC_INST_MTSPR_DSCR_MASK	0xfc1ffffe
73d2fb758e678c Anton Blanchard      2013-05-01  250  #define PPC_INST_MFSPR_DSCR_USER	0x7c0302a6
178f358208ceb8 Anton Blanchard      2017-01-19  251  #define PPC_INST_MFSPR_DSCR_USER_MASK	0xfc1ffffe
73d2fb758e678c Anton Blanchard      2013-05-01  252  #define PPC_INST_MTSPR_DSCR_USER	0x7c0303a6
178f358208ceb8 Anton Blanchard      2017-01-19  253  #define PPC_INST_MTSPR_DSCR_USER_MASK	0xfc1ffffe
6dd7a82cc54ebd Anton Blanchard      2016-07-01  254  #define PPC_INST_MFVSRD			0x7c000066
6dd7a82cc54ebd Anton Blanchard      2016-07-01  255  #define PPC_INST_MTVSRD			0x7c000166
d16952a629129c Christophe Leroy     2018-11-09  256  #define PPC_INST_SC			0x44000002
697d3899dcb4bc Paul Mackerras       2011-12-12  257  #define PPC_INST_SLBFEE			0x7c0007a7
09cf5bcb0c9355 Aneesh Kumar K.V     2016-07-13  258  #define PPC_INST_SLBIA			0x7c0003e4
16c57b3620d77e Kumar Gala           2009-02-10  259  

:::::: The code at line 234 was first introduced by commit
:::::: 16c57b3620d77e0bc981da5ef32beae730512684 powerpc: Unify opcode definitions and support

:::::: TO: Kumar Gala <galak@kernel.crashing.org>
:::::: CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06  9:52   ` Alistair Popple
  2020-04-06 10:25     ` Christophe Leroy
@ 2020-04-06 10:42     ` Jordan Niethe
  2020-04-07  1:39       ` Alistair Popple
  1 sibling, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06 10:42 UTC (permalink / raw)
  To: Alistair Popple; +Cc: npiggin, bala24, linuxppc-dev, dja

[-- Attachment #1: Type: text/plain, Size: 18341 bytes --]

On Mon, 6 Apr 2020, 7:52 pm Alistair Popple, <alistair@popple.id.au> wrote:

> > diff --git a/arch/powerpc/include/asm/inst.h
> > b/arch/powerpc/include/asm/inst.h index 70b37a35a91a..7e23e7146c66 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -8,23 +8,67 @@
> >
> >  struct ppc_inst {
> >          u32 val;
> > +#ifdef __powerpc64__
> > +        u32 suffix;
> > +#endif /* __powerpc64__ */
> >  } __packed;
> >
> > -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > +static inline int ppc_inst_opcode(struct ppc_inst x)
> > +{
> > +     return x.val >> 26;
> > +}
> >
> >  static inline u32 ppc_inst_val(struct ppc_inst x)
> >  {
> >       return x.val;
> >  }
> >
> > -static inline bool ppc_inst_len(struct ppc_inst x)
> > +#ifdef __powerpc64__
> > +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> > +
> > +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix =
> (y)
> > }) +
> > +static inline u32 ppc_inst_suffix(struct ppc_inst x)
> >  {
> > -     return sizeof(struct ppc_inst);
> > +     return x.suffix;
> >  }
> >
> > -static inline int ppc_inst_opcode(struct ppc_inst x)
> > +static inline bool ppc_inst_prefixed(struct ppc_inst x) {
> > +     return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) !=
> 0xff;
> > +}
> > +
> > +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> >  {
> > -     return x.val >> 26;
> > +     return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> > +                            swab32(ppc_inst_suffix(x)));
> > +}
> > +
> > +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > +{
> > +     u32 val, suffix = 0xff;
> > +     val = *(u32 *)ptr;
> > +     if ((val >> 26) == 1)
> > +             suffix = *((u32 *)ptr + 1);
> > +     return ppc_inst_prefix(val, suffix);
> > +}
> > +
> > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst
> x)
> > +{
> > +     if (ppc_inst_prefixed(x)) {
> > +             *(u32 *)ptr = x.val;
> > +             *((u32 *)ptr + 1) = x.suffix;
> > +     } else {
> > +             *(u32 *)ptr = x.val;
> > +     }
> > +}
> > +
> > +#else
> > +
> > +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > +
> > +static inline bool ppc_inst_prefixed(ppc_inst x)
> > +{
> > +     return 0;
> >  }
> >
> >  static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> > @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> > ppc_inst x) return ppc_inst(swab32(ppc_inst_val(x)));
> >  }
> >
> > +static inline u32 ppc_inst_val(struct ppc_inst x)
> > +{
> > +     return x.val;
> > +}
> > +
> >  static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> >  {
> >       return *ptr;
> >  }
> >
> > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst
> x)
> > +{
> > +     *ptr = x;
> > +}
> > +
> > +#endif /* __powerpc64__ */
> > +
> >  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
> >  {
> >       return !memcmp(&x, &y, sizeof(struct ppc_inst));
> >  }
>
> Apologies for not picking this up earlier, I was hoping to get to the
> bottom
> of the issue I was seeing before you sent out v5. However the above
> definition
> of instruction equality does not seem correct because it does not consider
> the
> case when an instruction is not prefixed - a non-prefixed instruction
> should be
> considered equal if the first 32-bit opcode/value is the same. Something
> like:
>
>         if (ppc_inst_prefixed(x) != ppc_inst_prefixed(y))
>                 return false;
>         else if (ppc_inst_prefixed(x))
>                 return !memcmp(&x, &y, sizeof(struct ppc_inst));
>         else
>                 return x.val == y.val;
>
> This was causing failures in ftrace_modify_code() as it would falsely
> detect
> two non-prefixed instructions as being not equal due to differences in the
> suffix.
>
Hm I was intending that non prefixed instructions would always have the
suffix set to the same value. If that's not happening, something must be
wrong with where the instructions are created.

>
> - Alistair
>
> > +static inline int ppc_inst_len(struct ppc_inst x)
> > +{
> > +     return (ppc_inst_prefixed(x)) ? 8  : 4;
> > +}
> > +
> >  #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/uaccess.h
> > b/arch/powerpc/include/asm/uaccess.h index c0a35e4586a5..5a3f486ddf02
> > 100644
> > --- a/arch/powerpc/include/asm/uaccess.h
> > +++ b/arch/powerpc/include/asm/uaccess.h
> > @@ -105,11 +105,34 @@ 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)))
> >
> > -#define __get_user_instr(x, ptr) \
> > -     __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> > +#define __get_user_instr(x, ptr)                     \
> > +({                                                   \
> > +     long __gui_ret = 0;                             \
> > +     unsigned int prefix, suffix;                    \
> > +     __gui_ret = __get_user(prefix, (unsigned int __user *)ptr);
>      \
> > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > +             __gui_ret = __get_user(suffix, (unsigned int __user *)ptr
> + 1); \
> > +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > +     } else {                                        \
> > +             (x) = ppc_inst(prefix);                 \
> > +     }                                               \
> > +     __gui_ret;                                      \
> > +})
> > +
> > +#define __get_user_instr_inatomic(x, ptr)            \
> > +({                                                   \
> > +     long __gui_ret = 0;                             \
> > +     unsigned int prefix, suffix;                    \
> > +     __gui_ret = __get_user_inatomic(prefix, (unsigned int __user
> *)ptr);            \
> > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > +             __gui_ret = __get_user_inatomic(suffix, (unsigned int
> __user *)ptr +
> > 1);   \ +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > +     } else {                                        \
> > +             (x) = ppc_inst(prefix);                 \
> > +     }                                               \
> > +     __gui_ret;                                      \
> > +})
> >
> > -#define __get_user_instr_inatomic(x, ptr) \
> > -     __get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
> >  extern long __put_user_bad(void);
> >
> >  /*
> > diff --git a/arch/powerpc/include/asm/uprobes.h
> > b/arch/powerpc/include/asm/uprobes.h index 7e3b329ba2d3..5bf65f5d44a9
> > 100644
> > --- a/arch/powerpc/include/asm/uprobes.h
> > +++ b/arch/powerpc/include/asm/uprobes.h
> > @@ -15,7 +15,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/optprobes.c
> > b/arch/powerpc/kernel/optprobes.c index 684640b8fa2e..689daf430161 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -159,38 +159,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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS
> |
> > ___PPC_RT(3) | +      /* lis reg,(op)@highest */
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS
> |
> > ___PPC_RT(reg) | ((val >> 48) & 0xffff)));
> >       addr++;
> >
> > -     /* ori r3,r3,(op)@higher */
> > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > ___PPC_RA(3) | -                        ___PPC_RS(3) | ((val >> 32) &
> 0xffff)));
> > +     /* ori reg,reg,(op)@higher */
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > ___PPC_RA(reg) | +                      ___PPC_RS(reg) | ((val >> 32) &
> 0xffff)));
> >       addr++;
> >
> > -     /* rldicr r3,r3,32,31 */
> > -     patch_instruction((struct ppc_inst *)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((struct ppc_inst *)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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> > ___PPC_RA(3) | -                        ___PPC_RS(3) | ((val >> 16) &
> 0xffff)));
> > +     /* oris reg,reg,(op)@h */
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> > ___PPC_RA(reg) | +                      ___PPC_RS(reg) | ((val >> 16) &
> 0xffff)));
> >       addr++;
> >
> > -     /* ori r3,r3,(op)@l */
> > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > ___PPC_RA(3) | -                        ___PPC_RS(3) | (val & 0xffff)));
> > +     /* ori reg,reg,(op)@l */
> > +     patch_instruction((struct ppc_inst *)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) {
> > -     struct ppc_inst branch_op_callback, branch_emulate_step;
> > +     struct 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;
> > @@ -240,7 +240,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()
> > @@ -271,7 +271,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(*p->ainsn.insn, buff + TMPL_INSN_IDX);
> > +     temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> > +     patch_imm64_load_insns(ppc_inst_val(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 e78742613b36..16041a5c86d5
> > 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -41,11 +41,35 @@
> >  #define      NUM_FTRACE_TRAMPS       8
> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> >
> > +#ifdef __powerpc64__
> >  static long
> >  probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> >  {
> > -     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> > +     u32 val, suffix = 0;
> > +     long err;
> > +
> > +     err = probe_kernel_read((void *)&val,
> > +                             src, sizeof(val));
> > +     if (err)
> > +             return err;
> > +
> > +     if ((val >> 26) == 1)
> > +             err = probe_kernel_read((void *)&suffix,
> > +                                     src + 4, MCOUNT_INSN_SIZE);
> > +     if (err)
> > +             return err;
> > +
> > +     *inst = ppc_inst_prefix(val, suffix);
> > +
> > +     return 0;
> >  }
> > +#else
> > +static long
> > +probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> > +{
> > +     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE)
> > +}
> > +#endif
> >
> >  static struct ppc_inst
> >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> > diff --git a/arch/powerpc/lib/code-patching.c
> > b/arch/powerpc/lib/code-patching.c index c329ad657302..b4007e03d8fa
> 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -24,12 +24,19 @@ static int __patch_instruction(struct ppc_inst
> > *exec_addr, struct ppc_inst instr {
> >       int err = 0;
> >
> > -     __put_user_asm(ppc_inst_val(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)) {
> > +             __put_user_asm(ppc_inst_val(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));
> > +     } else {
> > +             __put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
> ppc_inst_val(instr),
> > patch_addr, err, "std"); +            if (err)
> > +                     return err;
> > +             asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r"
> (patch_addr),
> > +                                                                 "r"
> (exec_addr));
> > +     }
> >
> >       return 0;
> >  }
> > diff --git a/arch/powerpc/lib/feature-fixups.c
> > b/arch/powerpc/lib/feature-fixups.c index f00dd13b1c3c..5519cec83cc8
> 100644
> > --- a/arch/powerpc/lib/feature-fixups.c
> > +++ b/arch/powerpc/lib/feature-fixups.c
> > @@ -84,12 +84,13 @@ static int patch_feature_section(unsigned long value,
> > struct fixup_entry *fcur) src = alt_start;
> >       dest = start;
> >
> > -     for (; src < alt_end; src++, dest++) {
> > +     for (; src < alt_end; src = (void *)src +
> > ppc_inst_len(ppc_inst_read(src)), +        (dest = (void *)dest +
> > ppc_inst_len(ppc_inst_read(dest)))) { if (patch_alt_instruction(src,
> dest,
> > alt_start, alt_end))
> >                       return 1;
> >       }
> >
> > -     for (; dest < end; dest++)
> > +     for (; dest < end; dest = (void *)dest +
> > ppc_inst_len(ppc_inst(PPC_INST_NOP))) raw_patch_instruction(dest,
> > ppc_inst(PPC_INST_NOP));
> >
> >       return 0;
> > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > index 52ddd3122dc8..8b285bf11218 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_val(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 6f3bcdcfc9c7..b704aebb099a 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -761,8 +761,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;
> >       }
> > @@ -863,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long
> > nip, unsigned long *offp) if (off >= sizeof(bpt_table))
> >               return NULL;
> >       *offp = off % BPT_SIZE;
> > -     if (*offp != 0 && *offp != 4)
> > +     if (*offp != 0 && *offp != 4 && *offp != 8)
> >               return NULL;
> >       return bpts + (off / BPT_SIZE);
> >  }
> > diff --git a/arch/powerpc/xmon/xmon_bpts.S
> b/arch/powerpc/xmon/xmon_bpts.S
> > index ebb2dbc70ca8..09058eb6abbd 100644
> > --- a/arch/powerpc/xmon/xmon_bpts.S
> > +++ b/arch/powerpc/xmon/xmon_bpts.S
> > @@ -3,6 +3,8 @@
> >  #include <asm/asm-compat.h>
> >  #include "xmon_bpts.h"
> >
> > +/* Prefixed instructions can not cross 64 byte boundaries */
> > +.align 6
> >  .global bpt_table
> >  bpt_table:
> > -     .space NBPTS * 8
> > +     .space NBPTS * 16
>
>
>
>
>

[-- Attachment #2: Type: text/html, Size: 23221 bytes --]

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06  8:09 ` [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
@ 2020-04-06 11:04     ` kbuild test robot
  2020-04-06 11:04     ` kbuild test robot
  2020-04-13 12:04   ` Balamuruhan S
  2 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 11:04 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: kbuild-all, Jordan Niethe, npiggin, bala24, alistair, linuxppc-dev, dja

[-- Attachment #1: Type: text/plain, Size: 14164 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from arch/powerpc/include/asm/sstep.h:5,
                    from arch/powerpc/kernel/align.c:26:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   In file included from include/linux/kernel.h:11,
                    from arch/powerpc/kernel/align.c:16:
   arch/powerpc/kernel/align.c: In function 'fix_alignment':
>> arch/powerpc/include/asm/uaccess.h:115:9: error: implicit declaration of function 'ppc_inst_prefix'; did you mean 'ppc_inst_read'? [-Werror=implicit-function-declaration]
     115 |   (x) = ppc_inst_prefix(prefix, suffix); \
         |         ^~~~~~~~~~~~~~~
   include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
      78 | # define unlikely(x) __builtin_expect(!!(x), 0)
         |                                          ^
>> arch/powerpc/kernel/align.c:307:15: note: in expansion of macro '__get_user_instr'
     307 |  if (unlikely(__get_user_instr(instr, (void __user *)regs->nip)))
         |               ^~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:115:9: error: incompatible types when assigning to type 'struct ppc_inst' from type 'int'
     115 |   (x) = ppc_inst_prefix(prefix, suffix); \
         |         ^~~~~~~~~~~~~~~
   include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
      78 | # define unlikely(x) __builtin_expect(!!(x), 0)
         |                                          ^
>> arch/powerpc/kernel/align.c:307:15: note: in expansion of macro '__get_user_instr'
     307 |  if (unlikely(__get_user_instr(instr, (void __user *)regs->nip)))
         |               ^~~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/kernel/process.c:60:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/kernel/setup_32.c:42:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   In file included from arch/powerpc/include/asm/asm-compat.h:6,
                    from arch/powerpc/include/asm/bitops.h:42,
                    from include/linux/bitops.h:29,
                    from include/linux/kernel.h:12,
                    from include/linux/list.h:9,
                    from include/linux/module.h:12,
                    from arch/powerpc/kernel/setup_32.c:6:
   arch/powerpc/kernel/setup_32.c: In function 'machine_init':
   arch/powerpc/include/asm/ppc-opcode.h:234:24: error: incompatible type for argument 2 of 'patch_instruction_site'
     234 | #define PPC_INST_NOP   0x60000000
         |                        ^~~~~~~~~~
         |                        |
         |                        int
   arch/powerpc/kernel/setup_32.c:89:49: note: in expansion of macro 'PPC_INST_NOP'
      89 |  patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
         |                                                 ^~~~~~~~~~~~
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:39:69: note: expected 'struct ppc_inst' but argument is of type 'int'
      39 | static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
         |                                                     ~~~~~~~~~~~~~~~~^~~~~
   arch/powerpc/kernel/setup_32.c:91:48: error: passing argument 1 of 'branch_target' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                                                ^~~~
         |                                                |
         |                                                unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:63:52: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      63 | unsigned long branch_target(const struct ppc_inst *instr);
         |                             ~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   arch/powerpc/kernel/setup_32.c:91:28: error: passing argument 2 of 'create_cond_branch' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                            ^~~~
         |                            |
         |                            unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:28:71: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      28 | int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
         |                                                ~~~~~~~~~~~~~~~~~~~~~~~^~~~
   arch/powerpc/kernel/setup_32.c:92:20: error: passing argument 1 of 'patch_instruction' from incompatible pointer type [-Werror=incompatible-pointer-types]
      92 |  patch_instruction(addr, insn); /* replace b by bne cr0 */
         |                    ^~~~
         |                    |
         |                    unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:31:40: note: expected 'struct ppc_inst *' but argument is of type 'unsigned int *'
      31 | int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
         |                       ~~~~~~~~~~~~~~~~~^~~~
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/include/asm/kprobes.h:24,
                    from include/linux/kprobes.h:30,
                    from arch/powerpc/lib/code-patching.c:7:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   In file included from include/linux/uaccess.h:11,
                    from arch/powerpc/include/asm/sections.h:7,
                    from include/linux/kallsyms.h:15,
                    from include/linux/ftrace.h:11,
                    from include/linux/kprobes.h:29,
                    from arch/powerpc/lib/code-patching.c:7:
   arch/powerpc/lib/code-patching.c: In function '__patch_instruction':
>> arch/powerpc/lib/code-patching.c:34:23: error: implicit declaration of function 'ppc_inst_suffix'; did you mean 'ppc_inst_swab'? [-Werror=implicit-function-declaration]
      34 |   __put_user_asm((u64)ppc_inst_suffix(instr) << 32 | ppc_inst_val(instr), patch_addr, err, "std");
         |                       ^~~~~~~~~~~~~~~
   arch/powerpc/include/asm/uaccess.h:153:10: note: in definition of macro '__put_user_asm'
     153 |   : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
         |          ^
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/include/asm/kprobes.h:24,
                    from include/linux/kprobes.h:30,
                    from arch/powerpc/lib/sstep.c:8:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   arch/powerpc/lib/sstep.c: In function 'analyse_instr':
>> arch/powerpc/lib/sstep.c:1176:11: error: implicit declaration of function 'ppc_inst_suffix'; did you mean 'ppc_inst_swab'? [-Werror=implicit-function-declaration]
    1176 |  suffix = ppc_inst_suffix(instr);
         |           ^~~~~~~~~~~~~~~
         |           ppc_inst_swab
   cc1: all warnings being treated as errors

vim +/ppc_inst +69 arch/powerpc/include/asm/inst.h

    68	
  > 69	static inline bool ppc_inst_prefixed(ppc_inst x)
    70	{
    71		return 0;
    72	}
    73	
    74	static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
    75	{
    76		return ppc_inst(swab32(ppc_inst_val(x)));
    77	}
    78	
  > 79	static inline u32 ppc_inst_val(struct ppc_inst x)
    80	{
    81		return x.val;
    82	}
    83	
    84	static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
    85	{
    86		return *ptr;
    87	}
    88	
    89	static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
    90	{
    91		*ptr = x;
    92	}
    93	
    94	#endif /* __powerpc64__ */
    95	
    96	static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
    97	{
    98		return !memcmp(&x, &y, sizeof(struct ppc_inst));
    99	}
   100	
   101	static inline int ppc_inst_len(struct ppc_inst x)
   102	{
 > 103		return (ppc_inst_prefixed(x)) ? 8  : 4;
   104	}
   105	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
@ 2020-04-06 11:04     ` kbuild test robot
  0 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 11:04 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 14415 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from arch/powerpc/include/asm/sstep.h:5,
                    from arch/powerpc/kernel/align.c:26:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   In file included from include/linux/kernel.h:11,
                    from arch/powerpc/kernel/align.c:16:
   arch/powerpc/kernel/align.c: In function 'fix_alignment':
>> arch/powerpc/include/asm/uaccess.h:115:9: error: implicit declaration of function 'ppc_inst_prefix'; did you mean 'ppc_inst_read'? [-Werror=implicit-function-declaration]
     115 |   (x) = ppc_inst_prefix(prefix, suffix); \
         |         ^~~~~~~~~~~~~~~
   include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
      78 | # define unlikely(x) __builtin_expect(!!(x), 0)
         |                                          ^
>> arch/powerpc/kernel/align.c:307:15: note: in expansion of macro '__get_user_instr'
     307 |  if (unlikely(__get_user_instr(instr, (void __user *)regs->nip)))
         |               ^~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:115:9: error: incompatible types when assigning to type 'struct ppc_inst' from type 'int'
     115 |   (x) = ppc_inst_prefix(prefix, suffix); \
         |         ^~~~~~~~~~~~~~~
   include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
      78 | # define unlikely(x) __builtin_expect(!!(x), 0)
         |                                          ^
>> arch/powerpc/kernel/align.c:307:15: note: in expansion of macro '__get_user_instr'
     307 |  if (unlikely(__get_user_instr(instr, (void __user *)regs->nip)))
         |               ^~~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/kernel/process.c:60:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/kernel/setup_32.c:42:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   In file included from arch/powerpc/include/asm/asm-compat.h:6,
                    from arch/powerpc/include/asm/bitops.h:42,
                    from include/linux/bitops.h:29,
                    from include/linux/kernel.h:12,
                    from include/linux/list.h:9,
                    from include/linux/module.h:12,
                    from arch/powerpc/kernel/setup_32.c:6:
   arch/powerpc/kernel/setup_32.c: In function 'machine_init':
   arch/powerpc/include/asm/ppc-opcode.h:234:24: error: incompatible type for argument 2 of 'patch_instruction_site'
     234 | #define PPC_INST_NOP   0x60000000
         |                        ^~~~~~~~~~
         |                        |
         |                        int
   arch/powerpc/kernel/setup_32.c:89:49: note: in expansion of macro 'PPC_INST_NOP'
      89 |  patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
         |                                                 ^~~~~~~~~~~~
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:39:69: note: expected 'struct ppc_inst' but argument is of type 'int'
      39 | static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
         |                                                     ~~~~~~~~~~~~~~~~^~~~~
   arch/powerpc/kernel/setup_32.c:91:48: error: passing argument 1 of 'branch_target' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                                                ^~~~
         |                                                |
         |                                                unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:63:52: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      63 | unsigned long branch_target(const struct ppc_inst *instr);
         |                             ~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   arch/powerpc/kernel/setup_32.c:91:28: error: passing argument 2 of 'create_cond_branch' from incompatible pointer type [-Werror=incompatible-pointer-types]
      91 |  create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
         |                            ^~~~
         |                            |
         |                            unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:28:71: note: expected 'const struct ppc_inst *' but argument is of type 'unsigned int *'
      28 | int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
         |                                                ~~~~~~~~~~~~~~~~~~~~~~~^~~~
   arch/powerpc/kernel/setup_32.c:92:20: error: passing argument 1 of 'patch_instruction' from incompatible pointer type [-Werror=incompatible-pointer-types]
      92 |  patch_instruction(addr, insn); /* replace b by bne cr0 */
         |                    ^~~~
         |                    |
         |                    unsigned int *
   In file included from arch/powerpc/kernel/setup_32.c:42:
   arch/powerpc/include/asm/code-patching.h:31:40: note: expected 'struct ppc_inst *' but argument is of type 'unsigned int *'
      31 | int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
         |                       ~~~~~~~~~~~~~~~~~^~~~
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/include/asm/kprobes.h:24,
                    from include/linux/kprobes.h:30,
                    from arch/powerpc/lib/code-patching.c:7:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   In file included from include/linux/uaccess.h:11,
                    from arch/powerpc/include/asm/sections.h:7,
                    from include/linux/kallsyms.h:15,
                    from include/linux/ftrace.h:11,
                    from include/linux/kprobes.h:29,
                    from arch/powerpc/lib/code-patching.c:7:
   arch/powerpc/lib/code-patching.c: In function '__patch_instruction':
>> arch/powerpc/lib/code-patching.c:34:23: error: implicit declaration of function 'ppc_inst_suffix'; did you mean 'ppc_inst_swab'? [-Werror=implicit-function-declaration]
      34 |   __put_user_asm((u64)ppc_inst_suffix(instr) << 32 | ppc_inst_val(instr), patch_addr, err, "std");
         |                       ^~~~~~~~~~~~~~~
   arch/powerpc/include/asm/uaccess.h:153:10: note: in definition of macro '__put_user_asm'
     153 |   : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
         |          ^
   cc1: all warnings being treated as errors
--
   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/include/asm/kprobes.h:24,
                    from include/linux/kprobes.h:30,
                    from arch/powerpc/lib/sstep.c:8:
>> arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
>> arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
>> arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   arch/powerpc/lib/sstep.c: In function 'analyse_instr':
>> arch/powerpc/lib/sstep.c:1176:11: error: implicit declaration of function 'ppc_inst_suffix'; did you mean 'ppc_inst_swab'? [-Werror=implicit-function-declaration]
    1176 |  suffix = ppc_inst_suffix(instr);
         |           ^~~~~~~~~~~~~~~
         |           ppc_inst_swab
   cc1: all warnings being treated as errors

vim +/ppc_inst +69 arch/powerpc/include/asm/inst.h

    68	
  > 69	static inline bool ppc_inst_prefixed(ppc_inst x)
    70	{
    71		return 0;
    72	}
    73	
    74	static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
    75	{
    76		return ppc_inst(swab32(ppc_inst_val(x)));
    77	}
    78	
  > 79	static inline u32 ppc_inst_val(struct ppc_inst x)
    80	{
    81		return x.val;
    82	}
    83	
    84	static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
    85	{
    86		return *ptr;
    87	}
    88	
    89	static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
    90	{
    91		*ptr = x;
    92	}
    93	
    94	#endif /* __powerpc64__ */
    95	
    96	static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
    97	{
    98		return !memcmp(&x, &y, sizeof(struct ppc_inst));
    99	}
   100	
   101	static inline int ppc_inst_len(struct ppc_inst x)
   102	{
 > 103		return (ppc_inst_prefixed(x)) ? 8  : 4;
   104	}
   105	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06 10:25     ` Christophe Leroy
@ 2020-04-06 11:13       ` Jordan Niethe
  2020-04-08 18:11       ` Segher Boessenkool
  1 sibling, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-06 11:13 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Alistair Popple, Nicholas Piggin, Balamuruhan S, linuxppc-dev,
	Daniel Axtens

On Mon, Apr 6, 2020 at 8:25 PM Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
>
>
> Le 06/04/2020 à 11:52, Alistair Popple a écrit :
>
> [...]
>
> >> @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> >> ppc_inst x) return ppc_inst(swab32(ppc_inst_val(x)));
> >>   }
> >>
> >> +static inline u32 ppc_inst_val(struct ppc_inst x)
> >> +{
> >> +    return x.val;
> >> +}
> >> +
> >>   static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> >>   {
> >>      return *ptr;
> >>   }
> >>
> >> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> >> +{
> >> +    *ptr = x;
> >> +}
> >> +
> >> +#endif /* __powerpc64__ */
> >> +
> >>   static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
> >>   {
> >>      return !memcmp(&x, &y, sizeof(struct ppc_inst));
> >>   }
> >
> > Apologies for not picking this up earlier, I was hoping to get to the bottom
> > of the issue I was seeing before you sent out v5. However the above definition
> > of instruction equality does not seem correct because it does not consider the
> > case when an instruction is not prefixed - a non-prefixed instruction should be
> > considered equal if the first 32-bit opcode/value is the same. Something like:
> >
> >       if (ppc_inst_prefixed(x) != ppc_inst_prefixed(y))
> >               return false;
> >       else if (ppc_inst_prefixed(x))
> >               return !memcmp(&x, &y, sizeof(struct ppc_inst));
>
> Are we sure memcmp() is a good candidate for the comparison ? Can we do
> simpler ? Especially, I understood a prefixed instruction is a 64 bits
> properly aligned instruction, can we do a simple u64 compare ? Or is GCC
> intelligent enough to do that without calling memcmp() function which is
> heavy ?
As it is GCC does call memcmp(). I'll try to make it simpler.
>
> >       else
> >               return x.val == y.val;
> >
> > This was causing failures in ftrace_modify_code() as it would falsely detect
> > two non-prefixed instructions as being not equal due to differences in the suffix.
> >
>
> Christophe

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

* Re: [PATCH v5 20/21] powerpc sstep: Add support for prefixed load/stores
  2020-04-06  8:09 ` [PATCH v5 20/21] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
@ 2020-04-06 11:29     ` kbuild test robot
  0 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 11:29 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: kbuild-all, Jordan Niethe, npiggin, bala24, alistair, linuxppc-dev, dja

[-- Attachment #1: Type: text/plain, Size: 8286 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/include/asm/kprobes.h:24,
                    from include/linux/kprobes.h:30,
                    from arch/powerpc/lib/sstep.c:8:
   arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
   arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
   arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   arch/powerpc/lib/sstep.c: In function 'analyse_instr':
   arch/powerpc/lib/sstep.c:1215:11: error: implicit declaration of function 'ppc_inst_suffix'; did you mean 'ppc_inst_swab'? [-Werror=implicit-function-declaration]
    1215 |  suffix = ppc_inst_suffix(instr);
         |           ^~~~~~~~~~~~~~~
         |           ppc_inst_swab
>> arch/powerpc/lib/sstep.c:1207:41: error: unused variable 'prefix_r' [-Werror=unused-variable]
    1207 |  unsigned int suffixopcode, prefixtype, prefix_r;
         |                                         ^~~~~~~~
>> arch/powerpc/lib/sstep.c:1207:29: error: unused variable 'prefixtype' [-Werror=unused-variable]
    1207 |  unsigned int suffixopcode, prefixtype, prefix_r;
         |                             ^~~~~~~~~~
>> arch/powerpc/lib/sstep.c:1207:15: error: unused variable 'suffixopcode' [-Werror=unused-variable]
    1207 |  unsigned int suffixopcode, prefixtype, prefix_r;
         |               ^~~~~~~~~~~~
   cc1: all warnings being treated as errors

vim +/prefix_r +1207 arch/powerpc/lib/sstep.c

  1191	
  1192	/*
  1193	 * Decode an instruction, and return information about it in *op
  1194	 * without changing *regs.
  1195	 * Integer arithmetic and logical instructions, branches, and barrier
  1196	 * instructions can be emulated just using the information in *op.
  1197	 *
  1198	 * Return value is 1 if the instruction can be emulated just by
  1199	 * updating *regs with the information in *op, -1 if we need the
  1200	 * GPRs but *regs doesn't contain the full register set, or 0
  1201	 * otherwise.
  1202	 */
  1203	int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
  1204			  struct ppc_inst instr)
  1205	{
  1206		unsigned int opcode, ra, rb, rc, rd, spr, u;
> 1207		unsigned int suffixopcode, prefixtype, prefix_r;
  1208		unsigned long int imm;
  1209		unsigned long int val, val2;
  1210		unsigned int mb, me, sh;
  1211		unsigned int word, suffix;
  1212		long ival;
  1213	
  1214		word = ppc_inst_val(instr);
  1215		suffix = ppc_inst_suffix(instr);
  1216	
  1217		op->type = COMPUTE;
  1218	
  1219		opcode = word >> 26;
  1220		switch (opcode) {
  1221		case 16:	/* bc */
  1222			op->type = BRANCH;
  1223			imm = (signed short)(word & 0xfffc);
  1224			if ((word & 2) == 0)
  1225				imm += regs->nip;
  1226			op->val = truncate_if_32bit(regs->msr, imm);
  1227			if (word & 1)
  1228				op->type |= SETLK;
  1229			if (branch_taken(word, regs, op))
  1230				op->type |= BRTAKEN;
  1231			return 1;
  1232	#ifdef CONFIG_PPC64
  1233		case 17:	/* sc */
  1234			if ((word & 0xfe2) == 2)
  1235				op->type = SYSCALL;
  1236			else
  1237				op->type = UNKNOWN;
  1238			return 0;
  1239	#endif
  1240		case 18:	/* b */
  1241			op->type = BRANCH | BRTAKEN;
  1242			imm = word & 0x03fffffc;
  1243			if (imm & 0x02000000)
  1244				imm -= 0x04000000;
  1245			if ((word & 2) == 0)
  1246				imm += regs->nip;
  1247			op->val = truncate_if_32bit(regs->msr, imm);
  1248			if (word & 1)
  1249				op->type |= SETLK;
  1250			return 1;
  1251		case 19:
  1252			switch ((word >> 1) & 0x3ff) {
  1253			case 0:		/* mcrf */
  1254				op->type = COMPUTE + SETCC;
  1255				rd = 7 - ((word >> 23) & 0x7);
  1256				ra = 7 - ((word >> 18) & 0x7);
  1257				rd *= 4;
  1258				ra *= 4;
  1259				val = (regs->ccr >> ra) & 0xf;
  1260				op->ccval = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
  1261				return 1;
  1262	
  1263			case 16:	/* bclr */
  1264			case 528:	/* bcctr */
  1265				op->type = BRANCH;
  1266				imm = (word & 0x400)? regs->ctr: regs->link;
  1267				op->val = truncate_if_32bit(regs->msr, imm);
  1268				if (word & 1)
  1269					op->type |= SETLK;
  1270				if (branch_taken(word, regs, op))
  1271					op->type |= BRTAKEN;
  1272				return 1;
  1273	
  1274			case 18:	/* rfid, scary */
  1275				if (regs->msr & MSR_PR)
  1276					goto priv;
  1277				op->type = RFI;
  1278				return 0;
  1279	
  1280			case 150:	/* isync */
  1281				op->type = BARRIER | BARRIER_ISYNC;
  1282				return 1;
  1283	
  1284			case 33:	/* crnor */
  1285			case 129:	/* crandc */
  1286			case 193:	/* crxor */
  1287			case 225:	/* crnand */
  1288			case 257:	/* crand */
  1289			case 289:	/* creqv */
  1290			case 417:	/* crorc */
  1291			case 449:	/* cror */
  1292				op->type = COMPUTE + SETCC;
  1293				ra = (word >> 16) & 0x1f;
  1294				rb = (word >> 11) & 0x1f;
  1295				rd = (word >> 21) & 0x1f;
  1296				ra = (regs->ccr >> (31 - ra)) & 1;
  1297				rb = (regs->ccr >> (31 - rb)) & 1;
  1298				val = (word >> (6 + ra * 2 + rb)) & 1;
  1299				op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
  1300					(val << (31 - rd));
  1301				return 1;
  1302			}
  1303			break;
  1304		case 31:
  1305			switch ((word >> 1) & 0x3ff) {
  1306			case 598:	/* sync */
  1307				op->type = BARRIER + BARRIER_SYNC;
  1308	#ifdef __powerpc64__
  1309				switch ((word >> 21) & 3) {
  1310				case 1:		/* lwsync */
  1311					op->type = BARRIER + BARRIER_LWSYNC;
  1312					break;
  1313				case 2:		/* ptesync */
  1314					op->type = BARRIER + BARRIER_PTESYNC;
  1315					break;
  1316				}
  1317	#endif
  1318				return 1;
  1319	
  1320			case 854:	/* eieio */
  1321				op->type = BARRIER + BARRIER_EIEIO;
  1322				return 1;
  1323			}
  1324			break;
  1325		}
  1326	
  1327		/* Following cases refer to regs->gpr[], so we need all regs */
  1328		if (!FULL_REGS(regs))
  1329			return -1;
  1330	
  1331		rd = (word >> 21) & 0x1f;
  1332		ra = (word >> 16) & 0x1f;
  1333		rb = (word >> 11) & 0x1f;
  1334		rc = (word >> 6) & 0x1f;
  1335	
  1336		switch (opcode) {
  1337	#ifdef __powerpc64__
  1338		case 2:		/* tdi */
  1339			if (rd & trap_compare(regs->gpr[ra], (short) word))
  1340				goto trap;
  1341			return 1;
  1342	#endif
  1343		case 3:		/* twi */
  1344			if (rd & trap_compare((int)regs->gpr[ra], (short) word))
  1345				goto trap;
  1346			return 1;
  1347	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 20/21] powerpc sstep: Add support for prefixed load/stores
@ 2020-04-06 11:29     ` kbuild test robot
  0 siblings, 0 replies; 71+ messages in thread
From: kbuild test robot @ 2020-04-06 11:29 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 8510 bytes --]

Hi Jordan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on v5.6]
[cannot apply to powerpc/next kvm-ppc/kvm-ppc-next scottwood/next next-20200406]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Jordan-Niethe/Initial-Prefixed-Instruction-support/20200406-165215
base:    7111951b8d4973bda27ff663f2cf18b663d15b48
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/powerpc/include/asm/code-patching.h:14,
                    from arch/powerpc/include/asm/kprobes.h:24,
                    from include/linux/kprobes.h:30,
                    from arch/powerpc/lib/sstep.c:8:
   arch/powerpc/include/asm/inst.h:69:38: error: unknown type name 'ppc_inst'
      69 | static inline bool ppc_inst_prefixed(ppc_inst x)
         |                                      ^~~~~~~~
   arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 'ppc_inst_val'
      79 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 'ppc_inst_val' was here
      21 | static inline u32 ppc_inst_val(struct ppc_inst x)
         |                   ^~~~~~~~~~~~
   arch/powerpc/include/asm/inst.h: In function 'ppc_inst_len':
   arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of function 'ppc_inst_prefixed'; did you mean 'ppc_inst_write'? [-Werror=implicit-function-declaration]
     103 |  return (ppc_inst_prefixed(x)) ? 8  : 4;
         |          ^~~~~~~~~~~~~~~~~
         |          ppc_inst_write
   arch/powerpc/lib/sstep.c: In function 'analyse_instr':
   arch/powerpc/lib/sstep.c:1215:11: error: implicit declaration of function 'ppc_inst_suffix'; did you mean 'ppc_inst_swab'? [-Werror=implicit-function-declaration]
    1215 |  suffix = ppc_inst_suffix(instr);
         |           ^~~~~~~~~~~~~~~
         |           ppc_inst_swab
>> arch/powerpc/lib/sstep.c:1207:41: error: unused variable 'prefix_r' [-Werror=unused-variable]
    1207 |  unsigned int suffixopcode, prefixtype, prefix_r;
         |                                         ^~~~~~~~
>> arch/powerpc/lib/sstep.c:1207:29: error: unused variable 'prefixtype' [-Werror=unused-variable]
    1207 |  unsigned int suffixopcode, prefixtype, prefix_r;
         |                             ^~~~~~~~~~
>> arch/powerpc/lib/sstep.c:1207:15: error: unused variable 'suffixopcode' [-Werror=unused-variable]
    1207 |  unsigned int suffixopcode, prefixtype, prefix_r;
         |               ^~~~~~~~~~~~
   cc1: all warnings being treated as errors

vim +/prefix_r +1207 arch/powerpc/lib/sstep.c

  1191	
  1192	/*
  1193	 * Decode an instruction, and return information about it in *op
  1194	 * without changing *regs.
  1195	 * Integer arithmetic and logical instructions, branches, and barrier
  1196	 * instructions can be emulated just using the information in *op.
  1197	 *
  1198	 * Return value is 1 if the instruction can be emulated just by
  1199	 * updating *regs with the information in *op, -1 if we need the
  1200	 * GPRs but *regs doesn't contain the full register set, or 0
  1201	 * otherwise.
  1202	 */
  1203	int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
  1204			  struct ppc_inst instr)
  1205	{
  1206		unsigned int opcode, ra, rb, rc, rd, spr, u;
> 1207		unsigned int suffixopcode, prefixtype, prefix_r;
  1208		unsigned long int imm;
  1209		unsigned long int val, val2;
  1210		unsigned int mb, me, sh;
  1211		unsigned int word, suffix;
  1212		long ival;
  1213	
  1214		word = ppc_inst_val(instr);
  1215		suffix = ppc_inst_suffix(instr);
  1216	
  1217		op->type = COMPUTE;
  1218	
  1219		opcode = word >> 26;
  1220		switch (opcode) {
  1221		case 16:	/* bc */
  1222			op->type = BRANCH;
  1223			imm = (signed short)(word & 0xfffc);
  1224			if ((word & 2) == 0)
  1225				imm += regs->nip;
  1226			op->val = truncate_if_32bit(regs->msr, imm);
  1227			if (word & 1)
  1228				op->type |= SETLK;
  1229			if (branch_taken(word, regs, op))
  1230				op->type |= BRTAKEN;
  1231			return 1;
  1232	#ifdef CONFIG_PPC64
  1233		case 17:	/* sc */
  1234			if ((word & 0xfe2) == 2)
  1235				op->type = SYSCALL;
  1236			else
  1237				op->type = UNKNOWN;
  1238			return 0;
  1239	#endif
  1240		case 18:	/* b */
  1241			op->type = BRANCH | BRTAKEN;
  1242			imm = word & 0x03fffffc;
  1243			if (imm & 0x02000000)
  1244				imm -= 0x04000000;
  1245			if ((word & 2) == 0)
  1246				imm += regs->nip;
  1247			op->val = truncate_if_32bit(regs->msr, imm);
  1248			if (word & 1)
  1249				op->type |= SETLK;
  1250			return 1;
  1251		case 19:
  1252			switch ((word >> 1) & 0x3ff) {
  1253			case 0:		/* mcrf */
  1254				op->type = COMPUTE + SETCC;
  1255				rd = 7 - ((word >> 23) & 0x7);
  1256				ra = 7 - ((word >> 18) & 0x7);
  1257				rd *= 4;
  1258				ra *= 4;
  1259				val = (regs->ccr >> ra) & 0xf;
  1260				op->ccval = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
  1261				return 1;
  1262	
  1263			case 16:	/* bclr */
  1264			case 528:	/* bcctr */
  1265				op->type = BRANCH;
  1266				imm = (word & 0x400)? regs->ctr: regs->link;
  1267				op->val = truncate_if_32bit(regs->msr, imm);
  1268				if (word & 1)
  1269					op->type |= SETLK;
  1270				if (branch_taken(word, regs, op))
  1271					op->type |= BRTAKEN;
  1272				return 1;
  1273	
  1274			case 18:	/* rfid, scary */
  1275				if (regs->msr & MSR_PR)
  1276					goto priv;
  1277				op->type = RFI;
  1278				return 0;
  1279	
  1280			case 150:	/* isync */
  1281				op->type = BARRIER | BARRIER_ISYNC;
  1282				return 1;
  1283	
  1284			case 33:	/* crnor */
  1285			case 129:	/* crandc */
  1286			case 193:	/* crxor */
  1287			case 225:	/* crnand */
  1288			case 257:	/* crand */
  1289			case 289:	/* creqv */
  1290			case 417:	/* crorc */
  1291			case 449:	/* cror */
  1292				op->type = COMPUTE + SETCC;
  1293				ra = (word >> 16) & 0x1f;
  1294				rb = (word >> 11) & 0x1f;
  1295				rd = (word >> 21) & 0x1f;
  1296				ra = (regs->ccr >> (31 - ra)) & 1;
  1297				rb = (regs->ccr >> (31 - rb)) & 1;
  1298				val = (word >> (6 + ra * 2 + rb)) & 1;
  1299				op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
  1300					(val << (31 - rd));
  1301				return 1;
  1302			}
  1303			break;
  1304		case 31:
  1305			switch ((word >> 1) & 0x3ff) {
  1306			case 598:	/* sync */
  1307				op->type = BARRIER + BARRIER_SYNC;
  1308	#ifdef __powerpc64__
  1309				switch ((word >> 21) & 3) {
  1310				case 1:		/* lwsync */
  1311					op->type = BARRIER + BARRIER_LWSYNC;
  1312					break;
  1313				case 2:		/* ptesync */
  1314					op->type = BARRIER + BARRIER_PTESYNC;
  1315					break;
  1316				}
  1317	#endif
  1318				return 1;
  1319	
  1320			case 854:	/* eieio */
  1321				op->type = BARRIER + BARRIER_EIEIO;
  1322				return 1;
  1323			}
  1324			break;
  1325		}
  1326	
  1327		/* Following cases refer to regs->gpr[], so we need all regs */
  1328		if (!FULL_REGS(regs))
  1329			return -1;
  1330	
  1331		rd = (word >> 21) & 0x1f;
  1332		ra = (word >> 16) & 0x1f;
  1333		rb = (word >> 11) & 0x1f;
  1334		rc = (word >> 6) & 0x1f;
  1335	
  1336		switch (opcode) {
  1337	#ifdef __powerpc64__
  1338		case 2:		/* tdi */
  1339			if (rd & trap_compare(regs->gpr[ra], (short) word))
  1340				goto trap;
  1341			return 1;
  1342	#endif
  1343		case 3:		/* twi */
  1344			if (rd & trap_compare((int)regs->gpr[ra], (short) word))
  1345				goto trap;
  1346			return 1;
  1347	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 6411 bytes --]

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06 10:42     ` Jordan Niethe
@ 2020-04-07  1:39       ` Alistair Popple
  0 siblings, 0 replies; 71+ messages in thread
From: Alistair Popple @ 2020-04-07  1:39 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: npiggin, bala24, linuxppc-dev, dja

On Monday, 6 April 2020 8:42:57 PM AEST Jordan Niethe wrote:
> On Mon, 6 Apr 2020, 7:52 pm Alistair Popple, <alistair@popple.id.au> wrote:
> > > diff --git a/arch/powerpc/include/asm/inst.h
> > > b/arch/powerpc/include/asm/inst.h index 70b37a35a91a..7e23e7146c66
> > > 100644
> > > --- a/arch/powerpc/include/asm/inst.h
> > > +++ b/arch/powerpc/include/asm/inst.h
> > > @@ -8,23 +8,67 @@
> > > 
> > >  struct ppc_inst {
> > >  
> > >          u32 val;
> > > 
> > > +#ifdef __powerpc64__
> > > +        u32 suffix;
> > > +#endif /* __powerpc64__ */
> > > 
> > >  } __packed;
> > > 
> > > -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > > +static inline int ppc_inst_opcode(struct ppc_inst x)
> > > +{
> > > +     return x.val >> 26;
> > > +}
> > > 
> > >  static inline u32 ppc_inst_val(struct ppc_inst x)
> > >  {
> > >  
> > >       return x.val;
> > >  
> > >  }
> > > 
> > > -static inline bool ppc_inst_len(struct ppc_inst x)
> > > +#ifdef __powerpc64__
> > > +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> > > +
> > > +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix =
> > 
> > (y)
> > 
> > > }) +
> > > +static inline u32 ppc_inst_suffix(struct ppc_inst x)
> > > 
> > >  {
> > > 
> > > -     return sizeof(struct ppc_inst);
> > > +     return x.suffix;
> > > 
> > >  }
> > > 
> > > -static inline int ppc_inst_opcode(struct ppc_inst x)
> > > +static inline bool ppc_inst_prefixed(struct ppc_inst x) {
> > > +     return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) !=
> > 
> > 0xff;
> > 
> > > +}
> > > +
> > > +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> > > 
> > >  {
> > > 
> > > -     return x.val >> 26;
> > > +     return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> > > +                            swab32(ppc_inst_suffix(x)));
> > > +}
> > > +
> > > +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > > +{
> > > +     u32 val, suffix = 0xff;
> > > +     val = *(u32 *)ptr;
> > > +     if ((val >> 26) == 1)
> > > +             suffix = *((u32 *)ptr + 1);
> > > +     return ppc_inst_prefix(val, suffix);
> > > +}
> > > +
> > > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst
> > 
> > x)
> > 
> > > +{
> > > +     if (ppc_inst_prefixed(x)) {
> > > +             *(u32 *)ptr = x.val;
> > > +             *((u32 *)ptr + 1) = x.suffix;
> > > +     } else {
> > > +             *(u32 *)ptr = x.val;
> > > +     }
> > > +}
> > > +
> > > +#else
> > > +
> > > +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > > +
> > > +static inline bool ppc_inst_prefixed(ppc_inst x)
> > > +{
> > > +     return 0;
> > > 
> > >  }
> > >  
> > >  static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> > > 
> > > @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> > > ppc_inst x) return ppc_inst(swab32(ppc_inst_val(x)));
> > > 
> > >  }
> > > 
> > > +static inline u32 ppc_inst_val(struct ppc_inst x)
> > > +{
> > > +     return x.val;
> > > +}
> > > +
> > > 
> > >  static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > >  {
> > >  
> > >       return *ptr;
> > >  
> > >  }
> > > 
> > > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst
> > 
> > x)
> > 
> > > +{
> > > +     *ptr = x;
> > > +}
> > > +
> > > +#endif /* __powerpc64__ */
> > > +
> > > 
> > >  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
> > >  {
> > >  
> > >       return !memcmp(&x, &y, sizeof(struct ppc_inst));
> > >  
> > >  }
> > 
> > Apologies for not picking this up earlier, I was hoping to get to the
> > bottom
> > of the issue I was seeing before you sent out v5. However the above
> > definition
> > of instruction equality does not seem correct because it does not consider
> > the
> > case when an instruction is not prefixed - a non-prefixed instruction
> > should be
> > considered equal if the first 32-bit opcode/value is the same. Something
> > 
> > like:
> >         if (ppc_inst_prefixed(x) != ppc_inst_prefixed(y))
> >         
> >                 return false;
> >         
> >         else if (ppc_inst_prefixed(x))
> >         
> >                 return !memcmp(&x, &y, sizeof(struct ppc_inst));
> >         
> >         else
> >         
> >                 return x.val == y.val;
> > 
> > This was causing failures in ftrace_modify_code() as it would falsely
> > detect
> > two non-prefixed instructions as being not equal due to differences in the
> > suffix.
> 
> Hm I was intending that non prefixed instructions would always have the
> suffix set to the same value. If that's not happening, something must be
> wrong with where the instructions are created.
> 

Ok, based on your comment I found the problem. Your last patch series defined 
read_inst() in  ftrace.c and ended that function with:

	ppc_inst_write(p, inst);
	return 0;

This is called from ftrace_modify_code(), where p is uninitialised. In the 
last series ppc_inst_write() function would only write/initialise the suffix if 
it was a prefixed instruction, hence leaving it uninitialised in this instance 
which lead to the problems checking equality.

I suspect read_instr() should have finished with this instead:

	*p = inst;
	return 0;

However your new patch series replaces it with probe_kernel_read_inst() which 
looks to do the right thing:

+       *inst = ppc_inst_prefix(val, suffix);
+
+       return 0;

As the suffix in *inst will always get written now, so my previous comment 
appears invalid.

- Alistair

> > - Alistair
> > 
> > > +static inline int ppc_inst_len(struct ppc_inst x)
> > > +{
> > > +     return (ppc_inst_prefixed(x)) ? 8  : 4;
> > > +}
> > > +
> > > 
> > >  #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/uaccess.h
> > > b/arch/powerpc/include/asm/uaccess.h index c0a35e4586a5..5a3f486ddf02
> > > 100644
> > > --- a/arch/powerpc/include/asm/uaccess.h
> > > +++ b/arch/powerpc/include/asm/uaccess.h
> > > @@ -105,11 +105,34 @@ 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)))
> > > 
> > > -#define __get_user_instr(x, ptr) \
> > > -     __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> > > +#define __get_user_instr(x, ptr)                     \
> > > +({                                                   \
> > > +     long __gui_ret = 0;                             \
> > > +     unsigned int prefix, suffix;                    \
> > > +     __gui_ret = __get_user(prefix, (unsigned int __user *)ptr);
> > > 
> >      \
> > > 
> > > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > > +             __gui_ret = __get_user(suffix, (unsigned int __user *)ptr
> > 
> > + 1); \
> > 
> > > +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > > +     } else {                                        \
> > > +             (x) = ppc_inst(prefix);                 \
> > > +     }                                               \
> > > +     __gui_ret;                                      \
> > > +})
> > > +
> > > +#define __get_user_instr_inatomic(x, ptr)            \
> > > +({                                                   \
> > > +     long __gui_ret = 0;                             \
> > > +     unsigned int prefix, suffix;                    \
> > > +     __gui_ret = __get_user_inatomic(prefix, (unsigned int __user
> > 
> > *)ptr);            \
> > 
> > > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > > +             __gui_ret = __get_user_inatomic(suffix, (unsigned int
> > 
> > __user *)ptr +
> > 
> > > 1);   \ +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > > +     } else {                                        \
> > > +             (x) = ppc_inst(prefix);                 \
> > > +     }                                               \
> > > +     __gui_ret;                                      \
> > > +})
> > > 
> > > -#define __get_user_instr_inatomic(x, ptr) \
> > > -     __get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
> > > 
> > >  extern long __put_user_bad(void);
> > >  
> > >  /*
> > > 
> > > diff --git a/arch/powerpc/include/asm/uprobes.h
> > > b/arch/powerpc/include/asm/uprobes.h index 7e3b329ba2d3..5bf65f5d44a9
> > > 100644
> > > --- a/arch/powerpc/include/asm/uprobes.h
> > > +++ b/arch/powerpc/include/asm/uprobes.h
> > > @@ -15,7 +15,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/optprobes.c
> > > b/arch/powerpc/kernel/optprobes.c index 684640b8fa2e..689daf430161
> > > 100644
> > > --- a/arch/powerpc/kernel/optprobes.c
> > > +++ b/arch/powerpc/kernel/optprobes.c
> > > @@ -159,38 +159,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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS
> > > 
> > > ___PPC_RT(3) | +      /* lis reg,(op)@highest */
> > > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS
> > > 
> > > ___PPC_RT(reg) | ((val >> 48) & 0xffff)));
> > > 
> > >       addr++;
> > > 
> > > -     /* ori r3,r3,(op)@higher */
> > > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > > ___PPC_RA(3) | -                        ___PPC_RS(3) | ((val >> 32) &
> > 
> > 0xffff)));
> > 
> > > +     /* ori reg,reg,(op)@higher */
> > > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > > ___PPC_RA(reg) | +                      ___PPC_RS(reg) | ((val >> 32) &
> > 
> > 0xffff)));
> > 
> > >       addr++;
> > > 
> > > -     /* rldicr r3,r3,32,31 */
> > > -     patch_instruction((struct ppc_inst *)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((struct ppc_inst *)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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS
> > > |
> > > ___PPC_RA(3) | -                        ___PPC_RS(3) | ((val >> 16) &
> > 
> > 0xffff)));
> > 
> > > +     /* oris reg,reg,(op)@h */
> > > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS
> > > |
> > > ___PPC_RA(reg) | +                      ___PPC_RS(reg) | ((val >> 16) &
> > 
> > 0xffff)));
> > 
> > >       addr++;
> > > 
> > > -     /* ori r3,r3,(op)@l */
> > > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > > ___PPC_RA(3) | -                        ___PPC_RS(3) | (val & 0xffff)));
> > > +     /* ori reg,reg,(op)@l */
> > > +     patch_instruction((struct ppc_inst *)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) {
> > > -     struct ppc_inst branch_op_callback, branch_emulate_step;
> > > +     struct 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;
> > > 
> > > @@ -240,7 +240,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()
> > > 
> > > @@ -271,7 +271,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(*p->ainsn.insn, buff + TMPL_INSN_IDX);
> > > +     temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> > > +     patch_imm64_load_insns(ppc_inst_val(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 e78742613b36..16041a5c86d5
> > > 100644
> > > --- a/arch/powerpc/kernel/trace/ftrace.c
> > > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > > @@ -41,11 +41,35 @@
> > > 
> > >  #define      NUM_FTRACE_TRAMPS       8
> > >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> > > 
> > > +#ifdef __powerpc64__
> > > 
> > >  static long
> > >  probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> > >  {
> > > 
> > > -     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> > > +     u32 val, suffix = 0;
> > > +     long err;
> > > +
> > > +     err = probe_kernel_read((void *)&val,
> > > +                             src, sizeof(val));
> > > +     if (err)
> > > +             return err;
> > > +
> > > +     if ((val >> 26) == 1)
> > > +             err = probe_kernel_read((void *)&suffix,
> > > +                                     src + 4, MCOUNT_INSN_SIZE);
> > > +     if (err)
> > > +             return err;
> > > +
> > > +     *inst = ppc_inst_prefix(val, suffix);
> > > +
> > > +     return 0;
> > > 
> > >  }
> > > 
> > > +#else
> > > +static long
> > > +probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> > > +{
> > > +     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE)
> > > +}
> > > +#endif
> > > 
> > >  static struct ppc_inst
> > >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> > > 
> > > diff --git a/arch/powerpc/lib/code-patching.c
> > > b/arch/powerpc/lib/code-patching.c index c329ad657302..b4007e03d8fa
> > 
> > 100644
> > 
> > > --- a/arch/powerpc/lib/code-patching.c
> > > +++ b/arch/powerpc/lib/code-patching.c
> > > @@ -24,12 +24,19 @@ static int __patch_instruction(struct ppc_inst
> > > *exec_addr, struct ppc_inst instr {
> > > 
> > >       int err = 0;
> > > 
> > > -     __put_user_asm(ppc_inst_val(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)) {
> > > +             __put_user_asm(ppc_inst_val(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));
> > 
> > > +     } else {
> > > +             __put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
> > 
> > ppc_inst_val(instr),
> > 
> > > patch_addr, err, "std"); +            if (err)
> > > +                     return err;
> > > +             asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r"
> > 
> > (patch_addr),
> > 
> > > +                                                                 "r"
> > 
> > (exec_addr));
> > 
> > > +     }
> > > 
> > >       return 0;
> > >  
> > >  }
> > > 
> > > diff --git a/arch/powerpc/lib/feature-fixups.c
> > > b/arch/powerpc/lib/feature-fixups.c index f00dd13b1c3c..5519cec83cc8
> > 
> > 100644
> > 
> > > --- a/arch/powerpc/lib/feature-fixups.c
> > > +++ b/arch/powerpc/lib/feature-fixups.c
> > > @@ -84,12 +84,13 @@ static int patch_feature_section(unsigned long
> > > value,
> > > struct fixup_entry *fcur) src = alt_start;
> > > 
> > >       dest = start;
> > > 
> > > -     for (; src < alt_end; src++, dest++) {
> > > +     for (; src < alt_end; src = (void *)src +
> > > ppc_inst_len(ppc_inst_read(src)), +        (dest = (void *)dest +
> > > ppc_inst_len(ppc_inst_read(dest)))) { if (patch_alt_instruction(src,
> > 
> > dest,
> > 
> > > alt_start, alt_end))
> > > 
> > >                       return 1;
> > >       
> > >       }
> > > 
> > > -     for (; dest < end; dest++)
> > > +     for (; dest < end; dest = (void *)dest +
> > > ppc_inst_len(ppc_inst(PPC_INST_NOP))) raw_patch_instruction(dest,
> > > ppc_inst(PPC_INST_NOP));
> > > 
> > >       return 0;
> > > 
> > > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > > index 52ddd3122dc8..8b285bf11218 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_val(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 6f3bcdcfc9c7..b704aebb099a 100644
> > > --- a/arch/powerpc/xmon/xmon.c
> > > +++ b/arch/powerpc/xmon/xmon.c
> > > @@ -761,8 +761,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;
> > >       
> > >       }
> > > 
> > > @@ -863,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long
> > > nip, unsigned long *offp) if (off >= sizeof(bpt_table))
> > > 
> > >               return NULL;
> > >       
> > >       *offp = off % BPT_SIZE;
> > > 
> > > -     if (*offp != 0 && *offp != 4)
> > > +     if (*offp != 0 && *offp != 4 && *offp != 8)
> > > 
> > >               return NULL;
> > >       
> > >       return bpts + (off / BPT_SIZE);
> > >  
> > >  }
> > > 
> > > diff --git a/arch/powerpc/xmon/xmon_bpts.S
> > 
> > b/arch/powerpc/xmon/xmon_bpts.S
> > 
> > > index ebb2dbc70ca8..09058eb6abbd 100644
> > > --- a/arch/powerpc/xmon/xmon_bpts.S
> > > +++ b/arch/powerpc/xmon/xmon_bpts.S
> > > @@ -3,6 +3,8 @@
> > > 
> > >  #include <asm/asm-compat.h>
> > >  #include "xmon_bpts.h"
> > > 
> > > +/* Prefixed instructions can not cross 64 byte boundaries */
> > > +.align 6
> > > 
> > >  .global bpt_table
> > > 
> > >  bpt_table:
> > > -     .space NBPTS * 8
> > > +     .space NBPTS * 16





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

* Re: [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al.
  2020-04-06  8:09 ` [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al Jordan Niethe
  2020-04-06 10:25     ` kbuild test robot
@ 2020-04-07  6:10   ` Balamuruhan S
  2020-04-07  6:35     ` Jordan Niethe
  1 sibling, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07  6:10 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> create_branch(), create_cond_branch() and translate_branch() return the
> instruction that they create, or return 0 to signal an error. Seperate

s/seperate/separate

> these concerns in preparation for an instruction type that is not just
> an unsigned int.  Fill the created instruction to a pointer passed as
> the first parameter to the function and use a non-zero return value to
> signify an error.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v5: New to series
> ---
>  arch/powerpc/include/asm/code-patching.h |  12 +-
>  arch/powerpc/kernel/optprobes.c          |  24 ++--
>  arch/powerpc/kernel/setup_32.c           |   2 +-
>  arch/powerpc/kernel/trace/ftrace.c       |  24 ++--
>  arch/powerpc/lib/code-patching.c         | 133 +++++++++++++----------
>  arch/powerpc/lib/feature-fixups.c        |   5 +-
>  6 files changed, 117 insertions(+), 83 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h
> b/arch/powerpc/include/asm/code-patching.h
> index 898b54262881..351dda7215b6 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -22,10 +22,10 @@
>  #define BRANCH_ABSOLUTE	0x2
>  
>  bool is_offset_in_branch_range(long offset);
> -unsigned int create_branch(const unsigned int *addr,
> -			   unsigned long target, int flags);
> -unsigned int create_cond_branch(const unsigned int *addr,
> -				unsigned long target, int flags);
> +int create_branch(unsigned int *instr, const unsigned int *addr,
> +		  unsigned long target, int flags);
> +int create_cond_branch(unsigned int *instr, const unsigned int *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);
> @@ -60,8 +60,8 @@ 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);
> +int translate_branch(unsigned int *instr, const unsigned int *dest,
> +		     const unsigned int *src);
>  extern bool is_conditional_branch(unsigned int instr);
>  #ifdef CONFIG_PPC_BOOK3E_64
>  void __patch_exception(int exc, unsigned long addr);
> diff --git a/arch/powerpc/kernel/optprobes.c
> b/arch/powerpc/kernel/optprobes.c
> index 024f7aad1952..445b3dad82dc 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -251,15 +251,17 @@ 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,
> -				(unsigned long)op_callback_addr,
> -				BRANCH_SET_LINK);
> +	rc = create_branch(&branch_op_callback,
> +			   (unsigned int *)buff + TMPL_CALL_HDLR_IDX,
> +			   (unsigned long)op_callback_addr,
> +			   BRANCH_SET_LINK);
>  
> -	branch_emulate_step = create_branch((unsigned int *)buff +
> TMPL_EMULATE_IDX,
> -				(unsigned long)emulate_step_addr,
> -				BRANCH_SET_LINK);
> +	rc |= create_branch(&branch_emulate_step,
> +			    (unsigned int *)buff + TMPL_EMULATE_IDX,
> +			    (unsigned long)emulate_step_addr,
> +			    BRANCH_SET_LINK);
>  
> -	if (!branch_op_callback || !branch_emulate_step)
> +	if (rc)
>  		goto error;
>  
>  	patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
> @@ -305,6 +307,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe
> *op)
>  
>  void arch_optimize_kprobes(struct list_head *oplist)
>  {
> +	unsigned int instr;
>  	struct optimized_kprobe *op;
>  	struct optimized_kprobe *tmp;
>  
> @@ -315,9 +318,10 @@ 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,
> -				      (unsigned long)op->optinsn.insn, 0));
> +		create_branch(&instr,
> +			      (unsigned int *)op->kp.addr,
> +			      (unsigned long)op->optinsn.insn, 0);
> +		patch_instruction(op->kp.addr, instr);
>  		list_del_init(&op->list);
>  	}
>  }
> diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
> index 5b49b26eb154..c1bdd462c5c0 100644
> --- a/arch/powerpc/kernel/setup_32.c
> +++ b/arch/powerpc/kernel/setup_32.c
> @@ -88,7 +88,7 @@ notrace void __init machine_init(u64 dt_ptr)
>  
>  	patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
>  
> -	insn = create_cond_branch(addr, branch_target(addr), 0x820000);
> +	create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
>  	patch_instruction(addr, insn);	/* replace b by bne cr0 */
>  
>  	/* Do some early initialization based on the flat device tree */
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c
> index 7ea0ca044b65..4dcb379133f8 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -48,7 +48,7 @@ ftrace_call_replace(unsigned long ip, unsigned long addr,
> int link)
>  	addr = ppc_function_entry((void *)addr);
>  
>  	/* if (link) set op to 'bl' else 'b' */
> -	op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> +	create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
>  
>  	return op;
>  }
> @@ -89,10 +89,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> unsigned int new)
>   */
>  static int test_24bit_addr(unsigned long ip, unsigned long addr)
>  {
> +	unsigned int op;
>  	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(&op, (unsigned int *)ip, addr, 0) == 0;
>  }
>  
>  static int is_bl_op(unsigned int op)
> @@ -287,6 +288,7 @@ __ftrace_make_nop(struct module *mod,
>  static unsigned long find_ftrace_tramp(unsigned long ip)
>  {
>  	int i;
> +	unsigned int instr;
>  
>  	/*
>  	 * We have the compiler generated long_branch tramps at the end
> @@ -295,7 +297,8 @@ 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 (create_branch(&instr, (void *)ip,
> +				  ftrace_tramps[i], 0) == 0)
>  			return ftrace_tramps[i];
>  
>  	return 0;
> @@ -324,6 +327,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> tramp)
>  {
>  	int i, op;
>  	unsigned long ptr;
> +	unsigned int instr;
>  	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
>  
>  	/* Is this a known long jump tramp? */
> @@ -366,7 +370,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 (create_branch(&instr, (void *)tramp, ptr, 0)) {
>  		pr_debug("%ps is not reachable from existing mcount tramp\n",
>  				(void *)ptr);
>  		return -1;
> @@ -511,6 +515,7 @@ static int
>  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
>  	unsigned int op[2];
> +	unsigned int instr;
>  	void *ip = (void *)rec->ip;
>  	unsigned long entry, ptr, tramp;
>  	struct module *mod = rec->arch.mod;
> @@ -557,7 +562,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 (create_branch(&instr, ip, tramp, BRANCH_SET_LINK)) {
>  		pr_err("Branch out of range\n");
>  		return -EINVAL;
>  	}
> @@ -574,6 +579,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  static int
>  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
> +	int err;
>  	unsigned int op;
>  	unsigned long ip = rec->ip;
>  
> @@ -594,9 +600,9 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  	}
>  
>  	/* create the branch to the trampoline */
> -	op = create_branch((unsigned int *)ip,
> -			   rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> -	if (!op) {
> +	err = create_branch(&op, (unsigned int *)ip,
> +			    rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> +	if (!err) {


should this be `if (err)` as per your new changes ?


>  		pr_err("REL24 out of range!\n");
>  		return -EINVAL;
>  	}
> @@ -776,7 +782,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(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
>  		pr_err("Branch out of range\n");
>  		return -EINVAL;
>  	}
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index 3345f039a876..4af564aeedf1 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -196,7 +196,10 @@ NOKPROBE_SYMBOL(patch_instruction);
>  
>  int patch_branch(unsigned int *addr, unsigned long target, int flags)
>  {
> -	return patch_instruction(addr, create_branch(addr, target, flags));
> +	unsigned int instr;
> +
> +	create_branch(&instr, addr, target, flags);
> +	return patch_instruction(addr, instr);
>  }
>  
>  bool is_offset_in_branch_range(long offset)
> @@ -243,30 +246,30 @@ bool is_conditional_branch(unsigned int instr)
>  }
>  NOKPROBE_SYMBOL(is_conditional_branch);
>  
> -unsigned int create_branch(const unsigned int *addr,
> -			   unsigned long target, int flags)
> +int create_branch(unsigned int *instr,
> +		  const unsigned int *addr,
> +		  unsigned long target, int flags)
>  {
> -	unsigned int instruction;
>  	long offset;
>  
> +	*instr = 0;
>  	offset = target;
>  	if (! (flags & BRANCH_ABSOLUTE))
>  		offset = offset - (unsigned long)addr;
>  
>  	/* Check we can represent the target in the instruction format */
>  	if (!is_offset_in_branch_range(offset))
> -		return 0;
> +		return 1;
>  
>  	/* Mask out the flags and target, so they don't step on each other. */
> -	instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
> +	*instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
>  
> -	return instruction;
> +	return 0;
>  }
>  
> -unsigned int create_cond_branch(const unsigned int *addr,
> -				unsigned long target, int flags)
> +int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> +		       unsigned long target, int flags)
>  {
> -	unsigned int instruction;
>  	long offset;
>  
>  	offset = target;
> @@ -275,12 +278,12 @@ 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 1;
>  
>  	/* Mask out the flags and target, so they don't step on each other. */
> -	instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
> +	*instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
>  
> -	return instruction;
> +	return 0;
>  }
>  
>  static unsigned int branch_opcode(unsigned int instr)
> @@ -361,18 +364,18 @@ 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)
> +int translate_branch(unsigned int *instr, const unsigned int *dest, const
> unsigned int *src)
>  {
>  	unsigned long target;
>  
>  	target = branch_target(src);
>  
>  	if (instr_is_branch_iform(*src))
> -		return create_branch(dest, target, *src);
> +		return create_branch(instr, dest, target, *src);
>  	else if (instr_is_branch_bform(*src))
> -		return create_cond_branch(dest, target, *src);
> +		return create_cond_branch(instr, dest, target, *src);
>  
> -	return 0;
> +	return 1;
>  }
>  
>  #ifdef CONFIG_PPC_BOOK3E_64
> @@ -403,6 +406,7 @@ static void __init test_trampoline(void)
>  
>  static void __init test_branch_iform(void)
>  {
> +	int err;
>  	unsigned int instr;
>  	unsigned long addr;
>  
> @@ -443,35 +447,35 @@ static void __init test_branch_iform(void)
>  	check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
>  
>  	/* Branch to self, with link */
> -	instr = create_branch(&instr, addr, BRANCH_SET_LINK);
> +	err = create_branch(&instr, &instr, addr, BRANCH_SET_LINK);
>  	check(instr_is_branch_to_addr(&instr, addr));
>  
>  	/* Branch to self - 0x100, with link */
> -	instr = create_branch(&instr, addr - 0x100, BRANCH_SET_LINK);
> +	err = create_branch(&instr, &instr, addr - 0x100, BRANCH_SET_LINK);
>  	check(instr_is_branch_to_addr(&instr, addr - 0x100));
>  
>  	/* Branch to self + 0x100, no link */
> -	instr = create_branch(&instr, addr + 0x100, 0);
> +	err = create_branch(&instr, &instr, addr + 0x100, 0);
>  	check(instr_is_branch_to_addr(&instr, addr + 0x100));
>  
>  	/* Maximum relative negative offset, - 32 MB */
> -	instr = create_branch(&instr, addr - 0x2000000, BRANCH_SET_LINK);
> +	err = create_branch(&instr, &instr, addr - 0x2000000, BRANCH_SET_LINK);
>  	check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
>  
>  	/* Out of range relative negative offset, - 32 MB + 4*/
> -	instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK);
> -	check(instr == 0);
> +	err = create_branch(&instr, &instr, addr - 0x2000004, BRANCH_SET_LINK);
> +	check(err);
>  
>  	/* Out of range relative positive offset, + 32 MB */
> -	instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK);
> -	check(instr == 0);
> +	err = create_branch(&instr, &instr, addr + 0x2000000, BRANCH_SET_LINK);
> +	check(err);
>  
>  	/* Unaligned target */
> -	instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK);
> -	check(instr == 0);
> +	err = create_branch(&instr, &instr, addr + 3, BRANCH_SET_LINK);
> +	check(err);
>  
>  	/* Check flags are masked correctly */
> -	instr = create_branch(&instr, addr, 0xFFFFFFFC);
> +	err = create_branch(&instr, &instr, addr, 0xFFFFFFFC);
>  	check(instr_is_branch_to_addr(&instr, addr));
>  	check(instr == 0x48000000);
>  }
> @@ -480,16 +484,19 @@ static void __init test_create_function_call(void)
>  {
>  	unsigned int *iptr;
>  	unsigned long dest;
> +	unsigned int instr;
>  
>  	/* Check we can create a function call */
>  	iptr = (unsigned int *)ppc_function_entry(test_trampoline);
>  	dest = ppc_function_entry(test_create_function_call);
> -	patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
> +	create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
> +	patch_instruction(iptr, instr);


Are we sure that `create_branch()` would always succeed here to do
patch_instruction() ?


>  	check(instr_is_branch_to_addr(iptr, dest));
>  }
>  
>  static void __init test_branch_bform(void)
>  {
> +	int err;
>  	unsigned long addr;
>  	unsigned int *iptr, instr, flags;
>  
> @@ -525,35 +532,35 @@ static void __init test_branch_bform(void)
>  	flags = 0x3ff000 | BRANCH_SET_LINK;
>  
>  	/* Branch to self */
> -	instr = create_cond_branch(iptr, addr, flags);
> +	err = create_cond_branch(&instr, iptr, addr, flags);
>  	check(instr_is_branch_to_addr(&instr, addr));
>  
>  	/* Branch to self - 0x100 */
> -	instr = create_cond_branch(iptr, addr - 0x100, flags);
> +	err = create_cond_branch(&instr, iptr, addr - 0x100, flags);
>  	check(instr_is_branch_to_addr(&instr, addr - 0x100));
>  
>  	/* Branch to self + 0x100 */
> -	instr = create_cond_branch(iptr, addr + 0x100, flags);
> +	err = create_cond_branch(&instr, iptr, addr + 0x100, flags);
>  	check(instr_is_branch_to_addr(&instr, addr + 0x100));
>  
>  	/* Maximum relative negative offset, - 32 KB */
> -	instr = create_cond_branch(iptr, addr - 0x8000, flags);
> +	err = create_cond_branch(&instr, iptr, addr - 0x8000, flags);
>  	check(instr_is_branch_to_addr(&instr, addr - 0x8000));
>  
>  	/* Out of range relative negative offset, - 32 KB + 4*/
> -	instr = create_cond_branch(iptr, addr - 0x8004, flags);
> -	check(instr == 0);
> +	err = create_cond_branch(&instr, iptr, addr - 0x8004, flags);
> +	check(err);
>  
>  	/* Out of range relative positive offset, + 32 KB */
> -	instr = create_cond_branch(iptr, addr + 0x8000, flags);
> -	check(instr == 0);
> +	err = create_cond_branch(&instr, iptr, addr + 0x8000, flags);
> +	check(err);
>  
>  	/* Unaligned target */
> -	instr = create_cond_branch(iptr, addr + 3, flags);
> -	check(instr == 0);
> +	err = create_cond_branch(&instr, iptr, addr + 3, flags);
> +	check(err);
>  
>  	/* Check flags are masked correctly */
> -	instr = create_cond_branch(iptr, addr, 0xFFFFFFFC);
> +	err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
>  	check(instr_is_branch_to_addr(&instr, addr));
>  	check(instr == 0x43FF0000);
>  }
> @@ -562,6 +569,7 @@ static void __init test_translate_branch(void)
>  {
>  	unsigned long addr;
>  	unsigned int *p, *q;
> +	unsigned int instr;
>  	void *buf;
>  
>  	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> @@ -575,7 +583,8 @@ static void __init test_translate_branch(void)
>  	patch_branch(p, addr, 0);
>  	check(instr_is_branch_to_addr(p, addr));
>  	q = p + 1;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);


same here and elsewhere in similar such places where we do patch_instruction()

-- Bala

>  	check(instr_is_branch_to_addr(q, addr));
>  
>  	/* Maximum negative case, move b . to addr + 32 MB */
> @@ -583,7 +592,8 @@ static void __init test_translate_branch(void)
>  	addr = (unsigned long)p;
>  	patch_branch(p, addr, 0);
>  	q = buf + 0x2000000;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  	check(*q == 0x4a000000);
> @@ -593,7 +603,8 @@ static void __init test_translate_branch(void)
>  	addr = (unsigned long)p;
>  	patch_branch(p, addr, 0);
>  	q = buf + 4;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  	check(*q == 0x49fffffc);
> @@ -603,7 +614,8 @@ static void __init test_translate_branch(void)
>  	addr = 0x1000000 + (unsigned long)buf;
>  	patch_branch(p, addr, BRANCH_SET_LINK);
>  	q = buf + 0x1400000;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  
> @@ -612,7 +624,8 @@ static void __init test_translate_branch(void)
>  	addr = 0x2000000 + (unsigned long)buf;
>  	patch_branch(p, addr, 0);
>  	q = buf + 4;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  
> @@ -622,18 +635,22 @@ static void __init test_translate_branch(void)
>  	/* Simple case, branch to self moved a little */
>  	p = buf;
>  	addr = (unsigned long)p;
> -	patch_instruction(p, create_cond_branch(p, addr, 0));
> +	create_cond_branch(&instr, p, addr, 0);
> +	patch_instruction(p, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	q = p + 1;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(q, addr));
>  
>  	/* Maximum negative case, move b . to addr + 32 KB */
>  	p = buf;
>  	addr = (unsigned long)p;
> -	patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
> +	create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
> +	patch_instruction(p, instr);
>  	q = buf + 0x8000;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  	check(*q == 0x43ff8000);
> @@ -641,9 +658,11 @@ static void __init test_translate_branch(void)
>  	/* Maximum positive case, move x to x - 32 KB + 4 */
>  	p = buf + 0x8000;
>  	addr = (unsigned long)p;
> -	patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
> +	create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
> +	patch_instruction(p, instr);
>  	q = buf + 4;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  	check(*q == 0x43ff7ffc);
> @@ -651,18 +670,22 @@ static void __init test_translate_branch(void)
>  	/* Jump to x + 12 KB moved to x + 20 KB */
>  	p = buf;
>  	addr = 0x3000 + (unsigned long)buf;
> -	patch_instruction(p, create_cond_branch(p, addr, BRANCH_SET_LINK));
> +	create_cond_branch(&instr, p, addr, BRANCH_SET_LINK);
> +	patch_instruction(p, instr);
>  	q = buf + 0x5000;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  
>  	/* Jump to x + 8 KB moved to x - 8 KB + 4 */
>  	p = buf + 0x2000;
>  	addr = 0x4000 + (unsigned long)buf;
> -	patch_instruction(p, create_cond_branch(p, addr, 0));
> +	create_cond_branch(&instr, p, addr, 0);
> +	patch_instruction(p, instr);
>  	q = buf + 4;
> -	patch_instruction(q, translate_branch(q, p));
> +	translate_branch(&instr, q, p);
> +	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
>  
> diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> fixups.c
> index 4ba634b89ce5..b129d7b4e7dd 100644
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -44,6 +44,7 @@ static unsigned int *calc_addr(struct fixup_entry *fcur,
> long offset)
>  static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
>  				 unsigned int *alt_start, unsigned int
> *alt_end)
>  {
> +	int err;
>  	unsigned int instr;
>  
>  	instr = *src;
> @@ -53,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 (!instr)
> +			err = translate_branch(&instr, dest, src);
> +			if (err)
>  				return 1;
>  		}
>  	}


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

* Re: [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al.
  2020-04-07  6:10   ` Balamuruhan S
@ 2020-04-07  6:35     ` Jordan Niethe
  2020-04-07  6:59       ` Balamuruhan S
  0 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-07  6:35 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, Nicholas Piggin, linuxppc-dev, Daniel Axtens

On Tue, Apr 7, 2020 at 4:10 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > create_branch(), create_cond_branch() and translate_branch() return the
> > instruction that they create, or return 0 to signal an error. Seperate
>
> s/seperate/separate
thanks.
>
> > these concerns in preparation for an instruction type that is not just
> > an unsigned int.  Fill the created instruction to a pointer passed as
> > the first parameter to the function and use a non-zero return value to
> > signify an error.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v5: New to series
> > ---
> >  arch/powerpc/include/asm/code-patching.h |  12 +-
> >  arch/powerpc/kernel/optprobes.c          |  24 ++--
> >  arch/powerpc/kernel/setup_32.c           |   2 +-
> >  arch/powerpc/kernel/trace/ftrace.c       |  24 ++--
> >  arch/powerpc/lib/code-patching.c         | 133 +++++++++++++----------
> >  arch/powerpc/lib/feature-fixups.c        |   5 +-
> >  6 files changed, 117 insertions(+), 83 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/code-patching.h
> > b/arch/powerpc/include/asm/code-patching.h
> > index 898b54262881..351dda7215b6 100644
> > --- a/arch/powerpc/include/asm/code-patching.h
> > +++ b/arch/powerpc/include/asm/code-patching.h
> > @@ -22,10 +22,10 @@
> >  #define BRANCH_ABSOLUTE      0x2
> >
> >  bool is_offset_in_branch_range(long offset);
> > -unsigned int create_branch(const unsigned int *addr,
> > -                        unsigned long target, int flags);
> > -unsigned int create_cond_branch(const unsigned int *addr,
> > -                             unsigned long target, int flags);
> > +int create_branch(unsigned int *instr, const unsigned int *addr,
> > +               unsigned long target, int flags);
> > +int create_cond_branch(unsigned int *instr, const unsigned int *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);
> > @@ -60,8 +60,8 @@ 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);
> > +int translate_branch(unsigned int *instr, const unsigned int *dest,
> > +                  const unsigned int *src);
> >  extern bool is_conditional_branch(unsigned int instr);
> >  #ifdef CONFIG_PPC_BOOK3E_64
> >  void __patch_exception(int exc, unsigned long addr);
> > diff --git a/arch/powerpc/kernel/optprobes.c
> > b/arch/powerpc/kernel/optprobes.c
> > index 024f7aad1952..445b3dad82dc 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -251,15 +251,17 @@ 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,
> > -                             (unsigned long)op_callback_addr,
> > -                             BRANCH_SET_LINK);
> > +     rc = create_branch(&branch_op_callback,
> > +                        (unsigned int *)buff + TMPL_CALL_HDLR_IDX,
> > +                        (unsigned long)op_callback_addr,
> > +                        BRANCH_SET_LINK);
> >
> > -     branch_emulate_step = create_branch((unsigned int *)buff +
> > TMPL_EMULATE_IDX,
> > -                             (unsigned long)emulate_step_addr,
> > -                             BRANCH_SET_LINK);
> > +     rc |= create_branch(&branch_emulate_step,
> > +                         (unsigned int *)buff + TMPL_EMULATE_IDX,
> > +                         (unsigned long)emulate_step_addr,
> > +                         BRANCH_SET_LINK);
> >
> > -     if (!branch_op_callback || !branch_emulate_step)
> > +     if (rc)
> >               goto error;
> >
> >       patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
> > @@ -305,6 +307,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe
> > *op)
> >
> >  void arch_optimize_kprobes(struct list_head *oplist)
> >  {
> > +     unsigned int instr;
> >       struct optimized_kprobe *op;
> >       struct optimized_kprobe *tmp;
> >
> > @@ -315,9 +318,10 @@ 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,
> > -                                   (unsigned long)op->optinsn.insn, 0));
> > +             create_branch(&instr,
> > +                           (unsigned int *)op->kp.addr,
> > +                           (unsigned long)op->optinsn.insn, 0);
> > +             patch_instruction(op->kp.addr, instr);
> >               list_del_init(&op->list);
> >       }
> >  }
> > diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
> > index 5b49b26eb154..c1bdd462c5c0 100644
> > --- a/arch/powerpc/kernel/setup_32.c
> > +++ b/arch/powerpc/kernel/setup_32.c
> > @@ -88,7 +88,7 @@ notrace void __init machine_init(u64 dt_ptr)
> >
> >       patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
> >
> > -     insn = create_cond_branch(addr, branch_target(addr), 0x820000);
> > +     create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
> >       patch_instruction(addr, insn);  /* replace b by bne cr0 */
> >
> >       /* Do some early initialization based on the flat device tree */
> > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > b/arch/powerpc/kernel/trace/ftrace.c
> > index 7ea0ca044b65..4dcb379133f8 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -48,7 +48,7 @@ ftrace_call_replace(unsigned long ip, unsigned long addr,
> > int link)
> >       addr = ppc_function_entry((void *)addr);
> >
> >       /* if (link) set op to 'bl' else 'b' */
> > -     op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> > +     create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
> >
> >       return op;
> >  }
> > @@ -89,10 +89,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> > unsigned int new)
> >   */
> >  static int test_24bit_addr(unsigned long ip, unsigned long addr)
> >  {
> > +     unsigned int op;
> >       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(&op, (unsigned int *)ip, addr, 0) == 0;
> >  }
> >
> >  static int is_bl_op(unsigned int op)
> > @@ -287,6 +288,7 @@ __ftrace_make_nop(struct module *mod,
> >  static unsigned long find_ftrace_tramp(unsigned long ip)
> >  {
> >       int i;
> > +     unsigned int instr;
> >
> >       /*
> >        * We have the compiler generated long_branch tramps at the end
> > @@ -295,7 +297,8 @@ 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 (create_branch(&instr, (void *)ip,
> > +                               ftrace_tramps[i], 0) == 0)
> >                       return ftrace_tramps[i];
> >
> >       return 0;
> > @@ -324,6 +327,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> > tramp)
> >  {
> >       int i, op;
> >       unsigned long ptr;
> > +     unsigned int instr;
> >       static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
> >
> >       /* Is this a known long jump tramp? */
> > @@ -366,7 +370,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 (create_branch(&instr, (void *)tramp, ptr, 0)) {
> >               pr_debug("%ps is not reachable from existing mcount tramp\n",
> >                               (void *)ptr);
> >               return -1;
> > @@ -511,6 +515,7 @@ static int
> >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> >  {
> >       unsigned int op[2];
> > +     unsigned int instr;
> >       void *ip = (void *)rec->ip;
> >       unsigned long entry, ptr, tramp;
> >       struct module *mod = rec->arch.mod;
> > @@ -557,7 +562,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 (create_branch(&instr, ip, tramp, BRANCH_SET_LINK)) {
> >               pr_err("Branch out of range\n");
> >               return -EINVAL;
> >       }
> > @@ -574,6 +579,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> > addr)
> >  static int
> >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> >  {
> > +     int err;
> >       unsigned int op;
> >       unsigned long ip = rec->ip;
> >
> > @@ -594,9 +600,9 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> > addr)
> >       }
> >
> >       /* create the branch to the trampoline */
> > -     op = create_branch((unsigned int *)ip,
> > -                        rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> > -     if (!op) {
> > +     err = create_branch(&op, (unsigned int *)ip,
> > +                         rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> > +     if (!err) {
>
>
> should this be `if (err)` as per your new changes ?
You are right.
>
>
> >               pr_err("REL24 out of range!\n");
> >               return -EINVAL;
> >       }
> > @@ -776,7 +782,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(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> >               pr_err("Branch out of range\n");
> >               return -EINVAL;
> >       }
> > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > patching.c
> > index 3345f039a876..4af564aeedf1 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -196,7 +196,10 @@ NOKPROBE_SYMBOL(patch_instruction);
> >
> >  int patch_branch(unsigned int *addr, unsigned long target, int flags)
> >  {
> > -     return patch_instruction(addr, create_branch(addr, target, flags));
> > +     unsigned int instr;
> > +
> > +     create_branch(&instr, addr, target, flags);
> > +     return patch_instruction(addr, instr);
> >  }
> >
> >  bool is_offset_in_branch_range(long offset)
> > @@ -243,30 +246,30 @@ bool is_conditional_branch(unsigned int instr)
> >  }
> >  NOKPROBE_SYMBOL(is_conditional_branch);
> >
> > -unsigned int create_branch(const unsigned int *addr,
> > -                        unsigned long target, int flags)
> > +int create_branch(unsigned int *instr,
> > +               const unsigned int *addr,
> > +               unsigned long target, int flags)
> >  {
> > -     unsigned int instruction;
> >       long offset;
> >
> > +     *instr = 0;
> >       offset = target;
> >       if (! (flags & BRANCH_ABSOLUTE))
> >               offset = offset - (unsigned long)addr;
> >
> >       /* Check we can represent the target in the instruction format */
> >       if (!is_offset_in_branch_range(offset))
> > -             return 0;
> > +             return 1;
> >
> >       /* Mask out the flags and target, so they don't step on each other. */
> > -     instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
> > +     *instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
> >
> > -     return instruction;
> > +     return 0;
> >  }
> >
> > -unsigned int create_cond_branch(const unsigned int *addr,
> > -                             unsigned long target, int flags)
> > +int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> > +                    unsigned long target, int flags)
> >  {
> > -     unsigned int instruction;
> >       long offset;
> >
> >       offset = target;
> > @@ -275,12 +278,12 @@ 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 1;
> >
> >       /* Mask out the flags and target, so they don't step on each other. */
> > -     instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
> > +     *instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
> >
> > -     return instruction;
> > +     return 0;
> >  }
> >
> >  static unsigned int branch_opcode(unsigned int instr)
> > @@ -361,18 +364,18 @@ 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)
> > +int translate_branch(unsigned int *instr, const unsigned int *dest, const
> > unsigned int *src)
> >  {
> >       unsigned long target;
> >
> >       target = branch_target(src);
> >
> >       if (instr_is_branch_iform(*src))
> > -             return create_branch(dest, target, *src);
> > +             return create_branch(instr, dest, target, *src);
> >       else if (instr_is_branch_bform(*src))
> > -             return create_cond_branch(dest, target, *src);
> > +             return create_cond_branch(instr, dest, target, *src);
> >
> > -     return 0;
> > +     return 1;
> >  }
> >
> >  #ifdef CONFIG_PPC_BOOK3E_64
> > @@ -403,6 +406,7 @@ static void __init test_trampoline(void)
> >
> >  static void __init test_branch_iform(void)
> >  {
> > +     int err;
> >       unsigned int instr;
> >       unsigned long addr;
> >
> > @@ -443,35 +447,35 @@ static void __init test_branch_iform(void)
> >       check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
> >
> >       /* Branch to self, with link */
> > -     instr = create_branch(&instr, addr, BRANCH_SET_LINK);
> > +     err = create_branch(&instr, &instr, addr, BRANCH_SET_LINK);
> >       check(instr_is_branch_to_addr(&instr, addr));
> >
> >       /* Branch to self - 0x100, with link */
> > -     instr = create_branch(&instr, addr - 0x100, BRANCH_SET_LINK);
> > +     err = create_branch(&instr, &instr, addr - 0x100, BRANCH_SET_LINK);
> >       check(instr_is_branch_to_addr(&instr, addr - 0x100));
> >
> >       /* Branch to self + 0x100, no link */
> > -     instr = create_branch(&instr, addr + 0x100, 0);
> > +     err = create_branch(&instr, &instr, addr + 0x100, 0);
> >       check(instr_is_branch_to_addr(&instr, addr + 0x100));
> >
> >       /* Maximum relative negative offset, - 32 MB */
> > -     instr = create_branch(&instr, addr - 0x2000000, BRANCH_SET_LINK);
> > +     err = create_branch(&instr, &instr, addr - 0x2000000, BRANCH_SET_LINK);
> >       check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
> >
> >       /* Out of range relative negative offset, - 32 MB + 4*/
> > -     instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK);
> > -     check(instr == 0);
> > +     err = create_branch(&instr, &instr, addr - 0x2000004, BRANCH_SET_LINK);
> > +     check(err);
> >
> >       /* Out of range relative positive offset, + 32 MB */
> > -     instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK);
> > -     check(instr == 0);
> > +     err = create_branch(&instr, &instr, addr + 0x2000000, BRANCH_SET_LINK);
> > +     check(err);
> >
> >       /* Unaligned target */
> > -     instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK);
> > -     check(instr == 0);
> > +     err = create_branch(&instr, &instr, addr + 3, BRANCH_SET_LINK);
> > +     check(err);
> >
> >       /* Check flags are masked correctly */
> > -     instr = create_branch(&instr, addr, 0xFFFFFFFC);
> > +     err = create_branch(&instr, &instr, addr, 0xFFFFFFFC);
> >       check(instr_is_branch_to_addr(&instr, addr));
> >       check(instr == 0x48000000);
> >  }
> > @@ -480,16 +484,19 @@ static void __init test_create_function_call(void)
> >  {
> >       unsigned int *iptr;
> >       unsigned long dest;
> > +     unsigned int instr;
> >
> >       /* Check we can create a function call */
> >       iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> >       dest = ppc_function_entry(test_create_function_call);
> > -     patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK));
> > +     create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
> > +     patch_instruction(iptr, instr);
>
>
> Are we sure that `create_branch()` would always succeed here to do
> patch_instruction() ?
>
>
> >       check(instr_is_branch_to_addr(iptr, dest));
> >  }
> >
> >  static void __init test_branch_bform(void)
> >  {
> > +     int err;
> >       unsigned long addr;
> >       unsigned int *iptr, instr, flags;
> >
> > @@ -525,35 +532,35 @@ static void __init test_branch_bform(void)
> >       flags = 0x3ff000 | BRANCH_SET_LINK;
> >
> >       /* Branch to self */
> > -     instr = create_cond_branch(iptr, addr, flags);
> > +     err = create_cond_branch(&instr, iptr, addr, flags);
> >       check(instr_is_branch_to_addr(&instr, addr));
> >
> >       /* Branch to self - 0x100 */
> > -     instr = create_cond_branch(iptr, addr - 0x100, flags);
> > +     err = create_cond_branch(&instr, iptr, addr - 0x100, flags);
> >       check(instr_is_branch_to_addr(&instr, addr - 0x100));
> >
> >       /* Branch to self + 0x100 */
> > -     instr = create_cond_branch(iptr, addr + 0x100, flags);
> > +     err = create_cond_branch(&instr, iptr, addr + 0x100, flags);
> >       check(instr_is_branch_to_addr(&instr, addr + 0x100));
> >
> >       /* Maximum relative negative offset, - 32 KB */
> > -     instr = create_cond_branch(iptr, addr - 0x8000, flags);
> > +     err = create_cond_branch(&instr, iptr, addr - 0x8000, flags);
> >       check(instr_is_branch_to_addr(&instr, addr - 0x8000));
> >
> >       /* Out of range relative negative offset, - 32 KB + 4*/
> > -     instr = create_cond_branch(iptr, addr - 0x8004, flags);
> > -     check(instr == 0);
> > +     err = create_cond_branch(&instr, iptr, addr - 0x8004, flags);
> > +     check(err);
> >
> >       /* Out of range relative positive offset, + 32 KB */
> > -     instr = create_cond_branch(iptr, addr + 0x8000, flags);
> > -     check(instr == 0);
> > +     err = create_cond_branch(&instr, iptr, addr + 0x8000, flags);
> > +     check(err);
> >
> >       /* Unaligned target */
> > -     instr = create_cond_branch(iptr, addr + 3, flags);
> > -     check(instr == 0);
> > +     err = create_cond_branch(&instr, iptr, addr + 3, flags);
> > +     check(err);
> >
> >       /* Check flags are masked correctly */
> > -     instr = create_cond_branch(iptr, addr, 0xFFFFFFFC);
> > +     err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
> >       check(instr_is_branch_to_addr(&instr, addr));
> >       check(instr == 0x43FF0000);
> >  }
> > @@ -562,6 +569,7 @@ static void __init test_translate_branch(void)
> >  {
> >       unsigned long addr;
> >       unsigned int *p, *q;
> > +     unsigned int instr;
> >       void *buf;
> >
> >       buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> > @@ -575,7 +583,8 @@ static void __init test_translate_branch(void)
> >       patch_branch(p, addr, 0);
> >       check(instr_is_branch_to_addr(p, addr));
> >       q = p + 1;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
>
>
> same here and elsewhere in similar such places where we do patch_instruction()
I figured that if the existing code was not checking the return then
we probably did not need to add a check.
>
> -- Bala
>
> >       check(instr_is_branch_to_addr(q, addr));
> >
> >       /* Maximum negative case, move b . to addr + 32 MB */
> > @@ -583,7 +592,8 @@ static void __init test_translate_branch(void)
> >       addr = (unsigned long)p;
> >       patch_branch(p, addr, 0);
> >       q = buf + 0x2000000;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >       check(*q == 0x4a000000);
> > @@ -593,7 +603,8 @@ static void __init test_translate_branch(void)
> >       addr = (unsigned long)p;
> >       patch_branch(p, addr, 0);
> >       q = buf + 4;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >       check(*q == 0x49fffffc);
> > @@ -603,7 +614,8 @@ static void __init test_translate_branch(void)
> >       addr = 0x1000000 + (unsigned long)buf;
> >       patch_branch(p, addr, BRANCH_SET_LINK);
> >       q = buf + 0x1400000;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >
> > @@ -612,7 +624,8 @@ static void __init test_translate_branch(void)
> >       addr = 0x2000000 + (unsigned long)buf;
> >       patch_branch(p, addr, 0);
> >       q = buf + 4;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >
> > @@ -622,18 +635,22 @@ static void __init test_translate_branch(void)
> >       /* Simple case, branch to self moved a little */
> >       p = buf;
> >       addr = (unsigned long)p;
> > -     patch_instruction(p, create_cond_branch(p, addr, 0));
> > +     create_cond_branch(&instr, p, addr, 0);
> > +     patch_instruction(p, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       q = p + 1;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(q, addr));
> >
> >       /* Maximum negative case, move b . to addr + 32 KB */
> >       p = buf;
> >       addr = (unsigned long)p;
> > -     patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
> > +     create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
> > +     patch_instruction(p, instr);
> >       q = buf + 0x8000;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >       check(*q == 0x43ff8000);
> > @@ -641,9 +658,11 @@ static void __init test_translate_branch(void)
> >       /* Maximum positive case, move x to x - 32 KB + 4 */
> >       p = buf + 0x8000;
> >       addr = (unsigned long)p;
> > -     patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
> > +     create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
> > +     patch_instruction(p, instr);
> >       q = buf + 4;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >       check(*q == 0x43ff7ffc);
> > @@ -651,18 +670,22 @@ static void __init test_translate_branch(void)
> >       /* Jump to x + 12 KB moved to x + 20 KB */
> >       p = buf;
> >       addr = 0x3000 + (unsigned long)buf;
> > -     patch_instruction(p, create_cond_branch(p, addr, BRANCH_SET_LINK));
> > +     create_cond_branch(&instr, p, addr, BRANCH_SET_LINK);
> > +     patch_instruction(p, instr);
> >       q = buf + 0x5000;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >
> >       /* Jump to x + 8 KB moved to x - 8 KB + 4 */
> >       p = buf + 0x2000;
> >       addr = 0x4000 + (unsigned long)buf;
> > -     patch_instruction(p, create_cond_branch(p, addr, 0));
> > +     create_cond_branch(&instr, p, addr, 0);
> > +     patch_instruction(p, instr);
> >       q = buf + 4;
> > -     patch_instruction(q, translate_branch(q, p));
> > +     translate_branch(&instr, q, p);
> > +     patch_instruction(q, instr);
> >       check(instr_is_branch_to_addr(p, addr));
> >       check(instr_is_branch_to_addr(q, addr));
> >
> > diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> > fixups.c
> > index 4ba634b89ce5..b129d7b4e7dd 100644
> > --- a/arch/powerpc/lib/feature-fixups.c
> > +++ b/arch/powerpc/lib/feature-fixups.c
> > @@ -44,6 +44,7 @@ static unsigned int *calc_addr(struct fixup_entry *fcur,
> > long offset)
> >  static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
> >                                unsigned int *alt_start, unsigned int
> > *alt_end)
> >  {
> > +     int err;
> >       unsigned int instr;
> >
> >       instr = *src;
> > @@ -53,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 (!instr)
> > +                     err = translate_branch(&instr, dest, src);
> > +                     if (err)
> >                               return 1;
> >               }
> >       }
>

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

* Re: [PATCH v5 04/21] powerpc: Use a macro for creating instructions from u32s
  2020-04-06  8:09 ` [PATCH v5 04/21] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
@ 2020-04-07  6:40   ` Balamuruhan S
  2020-04-07  8:27     ` Jordan Niethe
  0 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07  6:40 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> In preparation for instructions having a more complex data type start
> using a macro, ppc_inst(), for making an instruction out of a u32.  A
> macro is used so that instructions can be used as initializer elements.
> 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
> v5: - Rename PPC_INST() -> ppc_inst().
>     - Use on epapr_paravirt.c, kgdb.c
> ---
>  arch/powerpc/include/asm/code-patching.h |  3 +-
>  arch/powerpc/include/asm/inst.h          | 11 +++++
>  arch/powerpc/kernel/align.c              |  1 +
>  arch/powerpc/kernel/epapr_paravirt.c     |  5 ++-
>  arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
>  arch/powerpc/kernel/jump_label.c         |  3 +-
>  arch/powerpc/kernel/kgdb.c               |  5 ++-
>  arch/powerpc/kernel/kprobes.c            |  5 ++-
>  arch/powerpc/kernel/module_64.c          |  3 +-
>  arch/powerpc/kernel/optprobes.c          | 31 ++++++-------
>  arch/powerpc/kernel/security.c           |  9 ++--
>  arch/powerpc/kernel/trace/ftrace.c       | 25 ++++++-----
>  arch/powerpc/kernel/uprobes.c            |  1 +
>  arch/powerpc/kvm/emulate_loadstore.c     |  2 +-
>  arch/powerpc/lib/code-patching.c         | 57 ++++++++++++------------
>  arch/powerpc/lib/feature-fixups.c        | 39 ++++++++--------
>  arch/powerpc/lib/test_emulate_step.c     | 39 ++++++++--------
>  arch/powerpc/xmon/xmon.c                 |  7 +--
>  18 files changed, 138 insertions(+), 111 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 351dda7215b6..48e021957ee5 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);
> @@ -48,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/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> new file mode 100644
> index 000000000000..5298ba33b6e5
> --- /dev/null
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#ifndef _ASM_INST_H
> +#define _ASM_INST_H
> +
> +/*
> + * Instruction data type for POWER
> + */
> +
> +#define ppc_inst(x) (x)
> +
> +#endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index 92045ed64976..86e9bf62f18c 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -24,6 +24,7 @@
>  #include <asm/disassemble.h>
>  #include <asm/cpu_has_feature.h>
>  #include <asm/sstep.h>
> +#include <asm/inst.h>
>  
>  struct aligninfo {
>  	unsigned char len;
> diff --git a/arch/powerpc/kernel/epapr_paravirt.c
> b/arch/powerpc/kernel/epapr_paravirt.c
> index 9d32158ce36f..c53e863fb484 100644
> --- a/arch/powerpc/kernel/epapr_paravirt.c
> +++ b/arch/powerpc/kernel/epapr_paravirt.c
> @@ -11,6 +11,7 @@
>  #include <asm/cacheflush.h>
>  #include <asm/code-patching.h>
>  #include <asm/machdep.h>
> +#include <asm/inst.h>
>  
>  #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
>  extern void epapr_ev_idle(void);
> @@ -37,9 +38,9 @@ static int __init early_init_dt_scan_epapr(unsigned long
> node,
>  
>  	for (i = 0; i < (len / 4); i++) {
>  		u32 inst = be32_to_cpu(insts[i]);
> -		patch_instruction(epapr_hypercall_start + i, inst);
> +		patch_instruction(epapr_hypercall_start + i, ppc_inst(inst));
>  #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
> -		patch_instruction(epapr_ev_idle_start + i, inst);
> +		patch_instruction(epapr_ev_idle_start + i, ppc_inst(inst));


can we do it once while assigning inst ?

u32 inst = ppc_inst(be32_to_cpu(insts[i]));

-- Bala

>  #endif
>  	}
>  
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> b/arch/powerpc/kernel/hw_breakpoint.c
> index 2462cd7c565c..79f51f182a83 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;
> +	unsigned int 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..daa4afce7ec8 100644
> --- a/arch/powerpc/kernel/jump_label.c
> +++ b/arch/powerpc/kernel/jump_label.c
> @@ -6,6 +6,7 @@
>  #include <linux/kernel.h>
>  #include <linux/jump_label.h>
>  #include <asm/code-patching.h>
> +#include <asm/inst.h>
>  
>  void arch_jump_label_transform(struct jump_entry *entry,
>  			       enum jump_label_type type)
> @@ -15,5 +16,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/kgdb.c b/arch/powerpc/kernel/kgdb.c
> index 7dd55eb1259d..a6b38a19133f 100644
> --- a/arch/powerpc/kernel/kgdb.c
> +++ b/arch/powerpc/kernel/kgdb.c
> @@ -26,6 +26,7 @@
>  #include <asm/debug.h>
>  #include <asm/code-patching.h>
>  #include <linux/slab.h>
> +#include <asm/inst.h>
>  
>  /*
>   * This table contains the mapping between PowerPC hardware trap types, and
> @@ -424,7 +425,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
>  	if (err)
>  		return err;
>  
> -	err = patch_instruction(addr, BREAK_INSTR);
> +	err = patch_instruction(addr, ppc_inst(BREAK_INSTR));
>  	if (err)
>  		return -EFAULT;
>  
> @@ -439,7 +440,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
>  	unsigned int instr = *(unsigned int *)bpt->saved_instr;
>  	unsigned int *addr = (unsigned int *)bpt->bpt_addr;
>  
> -	err = patch_instruction(addr, instr);
> +	err = patch_instruction(addr, ppc_inst(instr));
>  	if (err)
>  		return -EFAULT;
>  
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 2d27ec4feee4..a1a3686f41c6 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -23,6 +23,7 @@
>  #include <asm/cacheflush.h>
>  #include <asm/sstep.h>
>  #include <asm/sections.h>
> +#include <asm/inst.h>
>  #include <linux/uaccess.h>
>  
>  DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
> @@ -138,13 +139,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..7fd6b29edcb2 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -20,6 +20,7 @@
>  #include <linux/sort.h>
>  #include <asm/setup.h>
>  #include <asm/sections.h>
> +#include <asm/inst.h>
>  
>  /* FIXME: We don't do .init separately.  To do this, we'd need to have
>     a separate r2 value in the init and core section, and stub between
> @@ -506,7 +507,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 445b3dad82dc..3b33ebf18859 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -16,6 +16,7 @@
>  #include <asm/code-patching.h>
>  #include <asm/sstep.h>
>  #include <asm/ppc-opcode.h>
> +#include <asm/inst.h>
>  
>  #define TMPL_CALL_HDLR_IDX	\
>  	(optprobe_template_call_handler - optprobe_template_entry)
> @@ -147,13 +148,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 +164,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 +231,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..81a288b1a603 100644
> --- a/arch/powerpc/kernel/security.c
> +++ b/arch/powerpc/kernel/security.c
> @@ -14,6 +14,7 @@
>  #include <asm/debugfs.h>
>  #include <asm/security_features.h>
>  #include <asm/setup.h>
> +#include <asm/inst.h>
>  
>  
>  u64 powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
> @@ -403,9 +404,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 +429,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 +440,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 4dcb379133f8..47233e671c18 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
> @@ -161,7 +162,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 +170,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 +189,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 +200,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 +276,7 @@ __ftrace_make_nop(struct module *mod,
>  		return -EINVAL;
>  	}
>  
> -	op = PPC_INST_NOP;
> +	op = ppc_inst(PPC_INST_NOP);
>  
>  	if (patch_instruction((unsigned int *)ip, op))
>  		return -EPERM;
> @@ -420,7 +421,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((unsigned int *)ip, ppc_inst(PPC_INST_NOP))) {
>  		pr_err("Patching NOP failed.\n");
>  		return -EPERM;
>  	}
> @@ -442,7 +443,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);
> @@ -496,7 +497,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> unsigned int 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 != ppc_inst(0x48000008)) || ((op1 & 0xffff0000) !=
> 0xe8410000))
>  		return 0;
>  	return 1;
>  }
> @@ -505,7 +506,7 @@ static int
>  expected_nop_sequence(void *ip, unsigned int op0, unsigned int 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;
>  }
> @@ -588,7 +589,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;
>  	}
> @@ -645,7 +646,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;
>  	}
> @@ -676,7 +677,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/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> index 1cfef0e5fec5..31c870287f2b 100644
> --- a/arch/powerpc/kernel/uprobes.c
> +++ b/arch/powerpc/kernel/uprobes.c
> @@ -14,6 +14,7 @@
>  #include <linux/kdebug.h>
>  
>  #include <asm/sstep.h>
> +#include <asm/inst.h>
>  
>  #define UPROBE_TRAP_NR	UINT_MAX
>  
> diff --git a/arch/powerpc/kvm/emulate_loadstore.c
> b/arch/powerpc/kvm/emulate_loadstore.c
> index 1139bc56e004..135d0e686622 100644
> --- a/arch/powerpc/kvm/emulate_loadstore.c
> +++ b/arch/powerpc/kvm/emulate_loadstore.c
> @@ -95,7 +95,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 4af564aeedf1..fdf0d6ea3575 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -17,6 +17,7 @@
>  #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)
> @@ -413,37 +414,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 */
> @@ -477,7 +478,7 @@ static void __init test_branch_iform(void)
>  	/* Check flags are masked correctly */
>  	err = create_branch(&instr, &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)
> @@ -504,28 +505,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 */
> @@ -562,7 +563,7 @@ static void __init test_branch_bform(void)
>  	/* Check flags are masked correctly */
>  	err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
>  	check(instr_is_branch_to_addr(&instr, addr));
> -	check(instr == 0x43FF0000);
> +	check(instr == ppc_inst(0x43FF0000));
>  }
>  
>  static void __init test_translate_branch(void)
> @@ -596,7 +597,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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;
> @@ -607,7 +608,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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;
> @@ -653,7 +654,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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;
> @@ -665,7 +666,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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 b129d7b4e7dd..6e7479b8887a 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;
> @@ -89,7 +90,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;
>  }
> @@ -146,15 +147,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,
> @@ -207,12 +208,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" :
> @@ -260,9 +261,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,
> @@ -295,7 +296,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);
> @@ -338,8 +339,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);
> @@ -353,7 +354,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));
>  	}
>  }
>  
> @@ -382,7 +383,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));
>  	}
>  }
>  
> @@ -400,7 +401,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 42347067739c..88b17226a493 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 049375206510..68ecb39dd9cc 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>
> @@ -949,7 +950,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(
>  			(unsigned int *)bp->address, bp->instr[0]) != 0)
>  			printf("Couldn't remove breakpoint at %lx\n",
> @@ -2845,7 +2846,7 @@ generic_inst_dump(unsigned long adr, long count, int
> praddr,
>  {
>  	int nr, dotted;
>  	unsigned long first_adr;
> -	unsigned int inst, last_inst = 0;
> +	unsigned int inst, last_inst = ppc_inst(0);
>  	unsigned char val[4];
>  
>  	dotted = 0;
> @@ -2858,7 +2859,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");


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

* Re: [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section
  2020-04-06  8:09 ` [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section Jordan Niethe
@ 2020-04-07  6:45   ` Balamuruhan S
  2020-04-09  6:11   ` Christophe Leroy
  1 sibling, 0 replies; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07  6:45 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, dja, npiggin

On Mon, 2020-04-06 at 18:09 +1000, 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]. Currently we only need
> the copied instruction followed by a trap, so 2 words per breakpoint.

we do 2 things here and we discussed to split it into 2 commits, may be
it is up to your thoughts and leave it to you. But otherwise rest looks
good to me.

-- Bala

> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> v5: - Do not use __section(), use a .space directive in .S file
>     - Simplify in_breakpoint_table() calculation
>     - Define BPT_SIZE
> ---
>  arch/powerpc/xmon/Makefile    |  2 +-
>  arch/powerpc/xmon/xmon.c      | 23 +++++++++++++----------
>  arch/powerpc/xmon/xmon_bpts.S |  8 ++++++++
>  arch/powerpc/xmon/xmon_bpts.h |  8 ++++++++
>  4 files changed, 30 insertions(+), 11 deletions(-)
>  create mode 100644 arch/powerpc/xmon/xmon_bpts.S
>  create mode 100644 arch/powerpc/xmon/xmon_bpts.h
> 
> diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
> index c3842dbeb1b7..515a13ea6f28 100644
> --- a/arch/powerpc/xmon/Makefile
> +++ b/arch/powerpc/xmon/Makefile
> @@ -21,7 +21,7 @@ endif
>  
>  ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
>  
> -obj-y			+= xmon.o nonstdio.o spr_access.o
> +obj-y			+= xmon.o nonstdio.o spr_access.o xmon_bpts.o
>  
>  ifdef CONFIG_XMON_DISASSEMBLY
>  obj-y			+= ppc-dis.o ppc-opc.o
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 02e3bd62cab4..049375206510 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -62,6 +62,7 @@
>  
>  #include "nonstdio.h"
>  #include "dis-asm.h"
> +#include "xmon_bpts.h"
>  
>  #ifdef CONFIG_SMP
>  static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
> @@ -97,7 +98,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;
> @@ -108,7 +109,6 @@ struct bpt {
>  #define BP_TRAP		2
>  #define BP_DABR		4
>  
> -#define NBPTS	256
>  static struct bpt bpts[NBPTS];
>  static struct bpt dabr;
>  static struct bpt *iabr;
> @@ -116,6 +116,10 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
>  
>  #define BP_NUM(bp)	((bp) - bpts + 1)
>  
> +#define BPT_SIZE	(sizeof(unsigned int) * 2)
> +#define BPT_WORDS	(BPT_SIZE / sizeof(unsigned int))
> +extern unsigned int bpt_table[NBPTS * BPT_WORDS];
> +
>  /* Prototypes */
>  static int cmds(struct pt_regs *);
>  static int mread(unsigned long, void *, int);
> @@ -853,15 +857,13 @@ static struct bpt *in_breakpoint_table(unsigned long
> nip, unsigned long *offp)
>  {
>  	unsigned long 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]))
> +	*offp = off % BPT_SIZE;
> +	if (*offp != 0 && *offp != 4)
>  		return NULL;
> -	*offp = off - offsetof(struct bpt, instr[0]);
> -	return (struct bpt *) (nip - off);
> +	return bpts + (off / BPT_SIZE);
>  }
>  
>  static struct bpt *new_breakpoint(unsigned long a)
> @@ -876,7 +878,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;
>  		}
>  	}
> diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
> new file mode 100644
> index 000000000000..ebb2dbc70ca8
> --- /dev/null
> +++ b/arch/powerpc/xmon/xmon_bpts.S
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <asm/ppc_asm.h>
> +#include <asm/asm-compat.h>
> +#include "xmon_bpts.h"
> +
> +.global bpt_table
> +bpt_table:
> +	.space NBPTS * 8
> diff --git a/arch/powerpc/xmon/xmon_bpts.h b/arch/powerpc/xmon/xmon_bpts.h
> new file mode 100644
> index 000000000000..840e70be7945
> --- /dev/null
> +++ b/arch/powerpc/xmon/xmon_bpts.h
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef XMON_BPTS_H
> +#define XMON_BPTS_H
> +
> +#define NBPTS	256
> +
> +#endif /* XMON_BPTS_H */
> +


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

* Re: [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al.
  2020-04-07  6:35     ` Jordan Niethe
@ 2020-04-07  6:59       ` Balamuruhan S
  0 siblings, 0 replies; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07  6:59 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Tue, 2020-04-07 at 16:35 +1000, Jordan Niethe wrote:
> On Tue, Apr 7, 2020 at 4:10 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
> > On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > > create_branch(), create_cond_branch() and translate_branch() return the
> > > instruction that they create, or return 0 to signal an error. Seperate
> > 
> > s/seperate/separate
> thanks.
> > > these concerns in preparation for an instruction type that is not just
> > > an unsigned int.  Fill the created instruction to a pointer passed as
> > > the first parameter to the function and use a non-zero return value to
> > > signify an error.
> > > 
> > > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > > ---
> > > v5: New to series
> > > ---
> > >  arch/powerpc/include/asm/code-patching.h |  12 +-
> > >  arch/powerpc/kernel/optprobes.c          |  24 ++--
> > >  arch/powerpc/kernel/setup_32.c           |   2 +-
> > >  arch/powerpc/kernel/trace/ftrace.c       |  24 ++--
> > >  arch/powerpc/lib/code-patching.c         | 133 +++++++++++++----------
> > >  arch/powerpc/lib/feature-fixups.c        |   5 +-
> > >  6 files changed, 117 insertions(+), 83 deletions(-)
> > > 
> > > diff --git a/arch/powerpc/include/asm/code-patching.h
> > > b/arch/powerpc/include/asm/code-patching.h
> > > index 898b54262881..351dda7215b6 100644
> > > --- a/arch/powerpc/include/asm/code-patching.h
> > > +++ b/arch/powerpc/include/asm/code-patching.h
> > > @@ -22,10 +22,10 @@
> > >  #define BRANCH_ABSOLUTE      0x2
> > > 
> > >  bool is_offset_in_branch_range(long offset);
> > > -unsigned int create_branch(const unsigned int *addr,
> > > -                        unsigned long target, int flags);
> > > -unsigned int create_cond_branch(const unsigned int *addr,
> > > -                             unsigned long target, int flags);
> > > +int create_branch(unsigned int *instr, const unsigned int *addr,
> > > +               unsigned long target, int flags);
> > > +int create_cond_branch(unsigned int *instr, const unsigned int *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);
> > > @@ -60,8 +60,8 @@ 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);
> > > +int translate_branch(unsigned int *instr, const unsigned int *dest,
> > > +                  const unsigned int *src);
> > >  extern bool is_conditional_branch(unsigned int instr);
> > >  #ifdef CONFIG_PPC_BOOK3E_64
> > >  void __patch_exception(int exc, unsigned long addr);
> > > diff --git a/arch/powerpc/kernel/optprobes.c
> > > b/arch/powerpc/kernel/optprobes.c
> > > index 024f7aad1952..445b3dad82dc 100644
> > > --- a/arch/powerpc/kernel/optprobes.c
> > > +++ b/arch/powerpc/kernel/optprobes.c
> > > @@ -251,15 +251,17 @@ 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,
> > > -                             (unsigned long)op_callback_addr,
> > > -                             BRANCH_SET_LINK);
> > > +     rc = create_branch(&branch_op_callback,
> > > +                        (unsigned int *)buff + TMPL_CALL_HDLR_IDX,
> > > +                        (unsigned long)op_callback_addr,
> > > +                        BRANCH_SET_LINK);
> > > 
> > > -     branch_emulate_step = create_branch((unsigned int *)buff +
> > > TMPL_EMULATE_IDX,
> > > -                             (unsigned long)emulate_step_addr,
> > > -                             BRANCH_SET_LINK);
> > > +     rc |= create_branch(&branch_emulate_step,
> > > +                         (unsigned int *)buff + TMPL_EMULATE_IDX,
> > > +                         (unsigned long)emulate_step_addr,
> > > +                         BRANCH_SET_LINK);
> > > 
> > > -     if (!branch_op_callback || !branch_emulate_step)
> > > +     if (rc)
> > >               goto error;
> > > 
> > >       patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
> > > @@ -305,6 +307,7 @@ int arch_check_optimized_kprobe(struct
> > > optimized_kprobe
> > > *op)
> > > 
> > >  void arch_optimize_kprobes(struct list_head *oplist)
> > >  {
> > > +     unsigned int instr;
> > >       struct optimized_kprobe *op;
> > >       struct optimized_kprobe *tmp;
> > > 
> > > @@ -315,9 +318,10 @@ 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,
> > > -                                   (unsigned long)op->optinsn.insn, 0));
> > > +             create_branch(&instr,
> > > +                           (unsigned int *)op->kp.addr,
> > > +                           (unsigned long)op->optinsn.insn, 0);
> > > +             patch_instruction(op->kp.addr, instr);
> > >               list_del_init(&op->list);
> > >       }
> > >  }
> > > diff --git a/arch/powerpc/kernel/setup_32.c
> > > b/arch/powerpc/kernel/setup_32.c
> > > index 5b49b26eb154..c1bdd462c5c0 100644
> > > --- a/arch/powerpc/kernel/setup_32.c
> > > +++ b/arch/powerpc/kernel/setup_32.c
> > > @@ -88,7 +88,7 @@ notrace void __init machine_init(u64 dt_ptr)
> > > 
> > >       patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
> > > 
> > > -     insn = create_cond_branch(addr, branch_target(addr), 0x820000);
> > > +     create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
> > >       patch_instruction(addr, insn);  /* replace b by bne cr0 */
> > > 
> > >       /* Do some early initialization based on the flat device tree */
> > > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > > b/arch/powerpc/kernel/trace/ftrace.c
> > > index 7ea0ca044b65..4dcb379133f8 100644
> > > --- a/arch/powerpc/kernel/trace/ftrace.c
> > > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > > @@ -48,7 +48,7 @@ ftrace_call_replace(unsigned long ip, unsigned long
> > > addr,
> > > int link)
> > >       addr = ppc_function_entry((void *)addr);
> > > 
> > >       /* if (link) set op to 'bl' else 'b' */
> > > -     op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
> > > +     create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
> > > 
> > >       return op;
> > >  }
> > > @@ -89,10 +89,11 @@ ftrace_modify_code(unsigned long ip, unsigned int
> > > old,
> > > unsigned int new)
> > >   */
> > >  static int test_24bit_addr(unsigned long ip, unsigned long addr)
> > >  {
> > > +     unsigned int op;
> > >       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(&op, (unsigned int *)ip, addr, 0) == 0;
> > >  }
> > > 
> > >  static int is_bl_op(unsigned int op)
> > > @@ -287,6 +288,7 @@ __ftrace_make_nop(struct module *mod,
> > >  static unsigned long find_ftrace_tramp(unsigned long ip)
> > >  {
> > >       int i;
> > > +     unsigned int instr;
> > > 
> > >       /*
> > >        * We have the compiler generated long_branch tramps at the end
> > > @@ -295,7 +297,8 @@ 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 (create_branch(&instr, (void *)ip,
> > > +                               ftrace_tramps[i], 0) == 0)
> > >                       return ftrace_tramps[i];
> > > 
> > >       return 0;
> > > @@ -324,6 +327,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> > > tramp)
> > >  {
> > >       int i, op;
> > >       unsigned long ptr;
> > > +     unsigned int instr;
> > >       static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
> > > 
> > >       /* Is this a known long jump tramp? */
> > > @@ -366,7 +370,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 (create_branch(&instr, (void *)tramp, ptr, 0)) {
> > >               pr_debug("%ps is not reachable from existing mcount
> > > tramp\n",
> > >                               (void *)ptr);
> > >               return -1;
> > > @@ -511,6 +515,7 @@ static int
> > >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > >  {
> > >       unsigned int op[2];
> > > +     unsigned int instr;
> > >       void *ip = (void *)rec->ip;
> > >       unsigned long entry, ptr, tramp;
> > >       struct module *mod = rec->arch.mod;
> > > @@ -557,7 +562,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 (create_branch(&instr, ip, tramp, BRANCH_SET_LINK)) {
> > >               pr_err("Branch out of range\n");
> > >               return -EINVAL;
> > >       }
> > > @@ -574,6 +579,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > long
> > > addr)
> > >  static int
> > >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> > >  {
> > > +     int err;
> > >       unsigned int op;
> > >       unsigned long ip = rec->ip;
> > > 
> > > @@ -594,9 +600,9 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned
> > > long
> > > addr)
> > >       }
> > > 
> > >       /* create the branch to the trampoline */
> > > -     op = create_branch((unsigned int *)ip,
> > > -                        rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> > > -     if (!op) {
> > > +     err = create_branch(&op, (unsigned int *)ip,
> > > +                         rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> > > +     if (!err) {
> > 
> > should this be `if (err)` as per your new changes ?
> You are right.
> > 
> > >               pr_err("REL24 out of range!\n");
> > >               return -EINVAL;
> > >       }
> > > @@ -776,7 +782,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(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK))
> > > {
> > >               pr_err("Branch out of range\n");
> > >               return -EINVAL;
> > >       }
> > > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > > patching.c
> > > index 3345f039a876..4af564aeedf1 100644
> > > --- a/arch/powerpc/lib/code-patching.c
> > > +++ b/arch/powerpc/lib/code-patching.c
> > > @@ -196,7 +196,10 @@ NOKPROBE_SYMBOL(patch_instruction);
> > > 
> > >  int patch_branch(unsigned int *addr, unsigned long target, int flags)
> > >  {
> > > -     return patch_instruction(addr, create_branch(addr, target, flags));
> > > +     unsigned int instr;
> > > +
> > > +     create_branch(&instr, addr, target, flags);
> > > +     return patch_instruction(addr, instr);
> > >  }
> > > 
> > >  bool is_offset_in_branch_range(long offset)
> > > @@ -243,30 +246,30 @@ bool is_conditional_branch(unsigned int instr)
> > >  }
> > >  NOKPROBE_SYMBOL(is_conditional_branch);
> > > 
> > > -unsigned int create_branch(const unsigned int *addr,
> > > -                        unsigned long target, int flags)
> > > +int create_branch(unsigned int *instr,
> > > +               const unsigned int *addr,
> > > +               unsigned long target, int flags)
> > >  {
> > > -     unsigned int instruction;
> > >       long offset;
> > > 
> > > +     *instr = 0;
> > >       offset = target;
> > >       if (! (flags & BRANCH_ABSOLUTE))
> > >               offset = offset - (unsigned long)addr;
> > > 
> > >       /* Check we can represent the target in the instruction format */
> > >       if (!is_offset_in_branch_range(offset))
> > > -             return 0;
> > > +             return 1;
> > > 
> > >       /* Mask out the flags and target, so they don't step on each other.
> > > */
> > > -     instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
> > > +     *instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
> > > 
> > > -     return instruction;
> > > +     return 0;
> > >  }
> > > 
> > > -unsigned int create_cond_branch(const unsigned int *addr,
> > > -                             unsigned long target, int flags)
> > > +int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> > > +                    unsigned long target, int flags)
> > >  {
> > > -     unsigned int instruction;
> > >       long offset;
> > > 
> > >       offset = target;
> > > @@ -275,12 +278,12 @@ 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 1;
> > > 
> > >       /* Mask out the flags and target, so they don't step on each other.
> > > */
> > > -     instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
> > > +     *instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
> > > 
> > > -     return instruction;
> > > +     return 0;
> > >  }
> > > 
> > >  static unsigned int branch_opcode(unsigned int instr)
> > > @@ -361,18 +364,18 @@ 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)
> > > +int translate_branch(unsigned int *instr, const unsigned int *dest,
> > > const
> > > unsigned int *src)
> > >  {
> > >       unsigned long target;
> > > 
> > >       target = branch_target(src);
> > > 
> > >       if (instr_is_branch_iform(*src))
> > > -             return create_branch(dest, target, *src);
> > > +             return create_branch(instr, dest, target, *src);
> > >       else if (instr_is_branch_bform(*src))
> > > -             return create_cond_branch(dest, target, *src);
> > > +             return create_cond_branch(instr, dest, target, *src);
> > > 
> > > -     return 0;
> > > +     return 1;
> > >  }
> > > 
> > >  #ifdef CONFIG_PPC_BOOK3E_64
> > > @@ -403,6 +406,7 @@ static void __init test_trampoline(void)
> > > 
> > >  static void __init test_branch_iform(void)
> > >  {
> > > +     int err;
> > >       unsigned int instr;
> > >       unsigned long addr;
> > > 
> > > @@ -443,35 +447,35 @@ static void __init test_branch_iform(void)
> > >       check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
> > > 
> > >       /* Branch to self, with link */
> > > -     instr = create_branch(&instr, addr, BRANCH_SET_LINK);
> > > +     err = create_branch(&instr, &instr, addr, BRANCH_SET_LINK);
> > >       check(instr_is_branch_to_addr(&instr, addr));
> > > 
> > >       /* Branch to self - 0x100, with link */
> > > -     instr = create_branch(&instr, addr - 0x100, BRANCH_SET_LINK);
> > > +     err = create_branch(&instr, &instr, addr - 0x100, BRANCH_SET_LINK);
> > >       check(instr_is_branch_to_addr(&instr, addr - 0x100));
> > > 
> > >       /* Branch to self + 0x100, no link */
> > > -     instr = create_branch(&instr, addr + 0x100, 0);
> > > +     err = create_branch(&instr, &instr, addr + 0x100, 0);
> > >       check(instr_is_branch_to_addr(&instr, addr + 0x100));
> > > 
> > >       /* Maximum relative negative offset, - 32 MB */
> > > -     instr = create_branch(&instr, addr - 0x2000000, BRANCH_SET_LINK);
> > > +     err = create_branch(&instr, &instr, addr - 0x2000000,
> > > BRANCH_SET_LINK);
> > >       check(instr_is_branch_to_addr(&instr, addr - 0x2000000));
> > > 
> > >       /* Out of range relative negative offset, - 32 MB + 4*/
> > > -     instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK);
> > > -     check(instr == 0);
> > > +     err = create_branch(&instr, &instr, addr - 0x2000004,
> > > BRANCH_SET_LINK);
> > > +     check(err);
> > > 
> > >       /* Out of range relative positive offset, + 32 MB */
> > > -     instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK);
> > > -     check(instr == 0);
> > > +     err = create_branch(&instr, &instr, addr + 0x2000000,
> > > BRANCH_SET_LINK);
> > > +     check(err);
> > > 
> > >       /* Unaligned target */
> > > -     instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK);
> > > -     check(instr == 0);
> > > +     err = create_branch(&instr, &instr, addr + 3, BRANCH_SET_LINK);
> > > +     check(err);
> > > 
> > >       /* Check flags are masked correctly */
> > > -     instr = create_branch(&instr, addr, 0xFFFFFFFC);
> > > +     err = create_branch(&instr, &instr, addr, 0xFFFFFFFC);
> > >       check(instr_is_branch_to_addr(&instr, addr));
> > >       check(instr == 0x48000000);
> > >  }
> > > @@ -480,16 +484,19 @@ static void __init test_create_function_call(void)
> > >  {
> > >       unsigned int *iptr;
> > >       unsigned long dest;
> > > +     unsigned int instr;
> > > 
> > >       /* Check we can create a function call */
> > >       iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> > >       dest = ppc_function_entry(test_create_function_call);
> > > -     patch_instruction(iptr, create_branch(iptr, dest,
> > > BRANCH_SET_LINK));
> > > +     create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
> > > +     patch_instruction(iptr, instr);
> > 
> > Are we sure that `create_branch()` would always succeed here to do
> > patch_instruction() ?
> > 
> > 
> > >       check(instr_is_branch_to_addr(iptr, dest));
> > >  }
> > > 
> > >  static void __init test_branch_bform(void)
> > >  {
> > > +     int err;
> > >       unsigned long addr;
> > >       unsigned int *iptr, instr, flags;
> > > 
> > > @@ -525,35 +532,35 @@ static void __init test_branch_bform(void)
> > >       flags = 0x3ff000 | BRANCH_SET_LINK;
> > > 
> > >       /* Branch to self */
> > > -     instr = create_cond_branch(iptr, addr, flags);
> > > +     err = create_cond_branch(&instr, iptr, addr, flags);
> > >       check(instr_is_branch_to_addr(&instr, addr));
> > > 
> > >       /* Branch to self - 0x100 */
> > > -     instr = create_cond_branch(iptr, addr - 0x100, flags);
> > > +     err = create_cond_branch(&instr, iptr, addr - 0x100, flags);
> > >       check(instr_is_branch_to_addr(&instr, addr - 0x100));
> > > 
> > >       /* Branch to self + 0x100 */
> > > -     instr = create_cond_branch(iptr, addr + 0x100, flags);
> > > +     err = create_cond_branch(&instr, iptr, addr + 0x100, flags);
> > >       check(instr_is_branch_to_addr(&instr, addr + 0x100));
> > > 
> > >       /* Maximum relative negative offset, - 32 KB */
> > > -     instr = create_cond_branch(iptr, addr - 0x8000, flags);
> > > +     err = create_cond_branch(&instr, iptr, addr - 0x8000, flags);
> > >       check(instr_is_branch_to_addr(&instr, addr - 0x8000));
> > > 
> > >       /* Out of range relative negative offset, - 32 KB + 4*/
> > > -     instr = create_cond_branch(iptr, addr - 0x8004, flags);
> > > -     check(instr == 0);
> > > +     err = create_cond_branch(&instr, iptr, addr - 0x8004, flags);
> > > +     check(err);
> > > 
> > >       /* Out of range relative positive offset, + 32 KB */
> > > -     instr = create_cond_branch(iptr, addr + 0x8000, flags);
> > > -     check(instr == 0);
> > > +     err = create_cond_branch(&instr, iptr, addr + 0x8000, flags);
> > > +     check(err);
> > > 
> > >       /* Unaligned target */
> > > -     instr = create_cond_branch(iptr, addr + 3, flags);
> > > -     check(instr == 0);
> > > +     err = create_cond_branch(&instr, iptr, addr + 3, flags);
> > > +     check(err);
> > > 
> > >       /* Check flags are masked correctly */
> > > -     instr = create_cond_branch(iptr, addr, 0xFFFFFFFC);
> > > +     err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
> > >       check(instr_is_branch_to_addr(&instr, addr));
> > >       check(instr == 0x43FF0000);
> > >  }
> > > @@ -562,6 +569,7 @@ static void __init test_translate_branch(void)
> > >  {
> > >       unsigned long addr;
> > >       unsigned int *p, *q;
> > > +     unsigned int instr;
> > >       void *buf;
> > > 
> > >       buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> > > @@ -575,7 +583,8 @@ static void __init test_translate_branch(void)
> > >       patch_branch(p, addr, 0);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       q = p + 1;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > 
> > same here and elsewhere in similar such places where we do
> > patch_instruction()
> I figured that if the existing code was not checking the return then
> we probably did not need to add a check.

yes existing code does not checking, I just wanted to ensure we do right
thing. Thanks!

-- Bala

> > -- Bala
> > 
> > >       check(instr_is_branch_to_addr(q, addr));
> > > 
> > >       /* Maximum negative case, move b . to addr + 32 MB */
> > > @@ -583,7 +592,8 @@ static void __init test_translate_branch(void)
> > >       addr = (unsigned long)p;
> > >       patch_branch(p, addr, 0);
> > >       q = buf + 0x2000000;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > >       check(*q == 0x4a000000);
> > > @@ -593,7 +603,8 @@ static void __init test_translate_branch(void)
> > >       addr = (unsigned long)p;
> > >       patch_branch(p, addr, 0);
> > >       q = buf + 4;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > >       check(*q == 0x49fffffc);
> > > @@ -603,7 +614,8 @@ static void __init test_translate_branch(void)
> > >       addr = 0x1000000 + (unsigned long)buf;
> > >       patch_branch(p, addr, BRANCH_SET_LINK);
> > >       q = buf + 0x1400000;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > > 
> > > @@ -612,7 +624,8 @@ static void __init test_translate_branch(void)
> > >       addr = 0x2000000 + (unsigned long)buf;
> > >       patch_branch(p, addr, 0);
> > >       q = buf + 4;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > > 
> > > @@ -622,18 +635,22 @@ static void __init test_translate_branch(void)
> > >       /* Simple case, branch to self moved a little */
> > >       p = buf;
> > >       addr = (unsigned long)p;
> > > -     patch_instruction(p, create_cond_branch(p, addr, 0));
> > > +     create_cond_branch(&instr, p, addr, 0);
> > > +     patch_instruction(p, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       q = p + 1;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(q, addr));
> > > 
> > >       /* Maximum negative case, move b . to addr + 32 KB */
> > >       p = buf;
> > >       addr = (unsigned long)p;
> > > -     patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
> > > +     create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
> > > +     patch_instruction(p, instr);
> > >       q = buf + 0x8000;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > >       check(*q == 0x43ff8000);
> > > @@ -641,9 +658,11 @@ static void __init test_translate_branch(void)
> > >       /* Maximum positive case, move x to x - 32 KB + 4 */
> > >       p = buf + 0x8000;
> > >       addr = (unsigned long)p;
> > > -     patch_instruction(p, create_cond_branch(p, addr, 0xFFFFFFFC));
> > > +     create_cond_branch(&instr, p, addr, 0xFFFFFFFC);
> > > +     patch_instruction(p, instr);
> > >       q = buf + 4;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > >       check(*q == 0x43ff7ffc);
> > > @@ -651,18 +670,22 @@ static void __init test_translate_branch(void)
> > >       /* Jump to x + 12 KB moved to x + 20 KB */
> > >       p = buf;
> > >       addr = 0x3000 + (unsigned long)buf;
> > > -     patch_instruction(p, create_cond_branch(p, addr, BRANCH_SET_LINK));
> > > +     create_cond_branch(&instr, p, addr, BRANCH_SET_LINK);
> > > +     patch_instruction(p, instr);
> > >       q = buf + 0x5000;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > > 
> > >       /* Jump to x + 8 KB moved to x - 8 KB + 4 */
> > >       p = buf + 0x2000;
> > >       addr = 0x4000 + (unsigned long)buf;
> > > -     patch_instruction(p, create_cond_branch(p, addr, 0));
> > > +     create_cond_branch(&instr, p, addr, 0);
> > > +     patch_instruction(p, instr);
> > >       q = buf + 4;
> > > -     patch_instruction(q, translate_branch(q, p));
> > > +     translate_branch(&instr, q, p);
> > > +     patch_instruction(q, instr);
> > >       check(instr_is_branch_to_addr(p, addr));
> > >       check(instr_is_branch_to_addr(q, addr));
> > > 
> > > diff --git a/arch/powerpc/lib/feature-fixups.c
> > > b/arch/powerpc/lib/feature-
> > > fixups.c
> > > index 4ba634b89ce5..b129d7b4e7dd 100644
> > > --- a/arch/powerpc/lib/feature-fixups.c
> > > +++ b/arch/powerpc/lib/feature-fixups.c
> > > @@ -44,6 +44,7 @@ static unsigned int *calc_addr(struct fixup_entry
> > > *fcur,
> > > long offset)
> > >  static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
> > >                                unsigned int *alt_start, unsigned int
> > > *alt_end)
> > >  {
> > > +     int err;
> > >       unsigned int instr;
> > > 
> > >       instr = *src;
> > > @@ -53,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 (!instr)
> > > +                     err = translate_branch(&instr, dest, src);
> > > +                     if (err)
> > >                               return 1;
> > >               }
> > >       }


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

* Re: [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code
  2020-04-06  8:09 ` [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code Jordan Niethe
  2020-04-06  8:22   ` Christophe Leroy
@ 2020-04-07  7:04   ` Balamuruhan S
  2020-04-07  8:32     ` Jordan Niethe
  2020-04-08 18:21   ` Segher Boessenkool
  2 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07  7:04 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, 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.

vecemu.c and sstep.c will need ppc_inst_opcode().

-- Bala

> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v4: New to series
> ---
>  arch/powerpc/include/asm/inst.h  | 5 +++++
>  arch/powerpc/kernel/align.c      | 2 +-
>  arch/powerpc/lib/code-patching.c | 4 ++--
>  3 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> index 5298ba33b6e5..93959016fe4b 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -8,4 +8,9 @@
>  
>  #define ppc_inst(x) (x)
>  
> +static inline int ppc_inst_opcode(u32 x)
> +{
> +	return x >> 26;
> +}
> +
>  #endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index 86e9bf62f18c..691013aa9f3c 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -314,7 +314,7 @@ int fix_alignment(struct pt_regs *regs)
>  	}
>  
>  #ifdef CONFIG_SPE
> -	if ((instr >> 26) == 0x4) {
> +	if (ppc_inst_opcode(instr) == 0x4) {
>  		int reg = (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 fdf0d6ea3575..099a515202aa 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -231,7 +231,7 @@ bool is_offset_in_branch_range(long offset)
>   */
>  bool is_conditional_branch(unsigned int instr)
>  {
> -	unsigned int opcode = instr >> 26;
> +	unsigned int opcode = ppc_inst_opcode(instr);
>  
>  	if (opcode == 16)       /* bc, bca, bcl, bcla */
>  		return true;
> @@ -289,7 +289,7 @@ int create_cond_branch(unsigned int *instr, const
> unsigned int *addr,
>  
>  static unsigned int branch_opcode(unsigned int instr)
>  {
> -	return (instr >> 26) & 0x3F;
> +	return ppc_inst_opcode(instr) & 0x3F;
>  }
>  
>  static int instr_is_branch_iform(unsigned int instr)


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

* Re: [PATCH v5 08/21] powerpc: Introduce functions for instruction equality
  2020-04-06  8:09 ` [PATCH v5 08/21] powerpc: Introduce functions for instruction equality Jordan Niethe
@ 2020-04-07  7:37   ` Balamuruhan S
  0 siblings, 0 replies; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07  7:37 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> In preparation for an instruction data type that can not be directly
> used with the '==' operator use functions for checking equality.

LGTM except one comment below, otherwise

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

> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v5: Remove ppc_inst_null()
> ---
>  arch/powerpc/include/asm/inst.h      |  5 +++++
>  arch/powerpc/kernel/trace/ftrace.c   | 15 ++++++++-------
>  arch/powerpc/lib/code-patching.c     | 12 ++++++------
>  arch/powerpc/lib/test_emulate_step.c |  2 +-
>  arch/powerpc/xmon/xmon.c             |  4 ++--
>  5 files changed, 22 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> index 78eb1481f1f6..54ee46b0a7c9 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -23,4 +23,9 @@ static inline u32 ppc_inst_swab(u32 x)
>  	return ppc_inst(swab32(ppc_inst_val(x)));
>  }
>  
> +static inline bool ppc_inst_equal(u32 x, u32 y)
> +{
> +	return x == y;
> +}
> +
>  #endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c
> index 62ff429bddc4..784b5746cc55 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, unsigned int old,
> unsigned int 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, ppc_inst_val(replaced), ppc_inst_val(old));
>  		return -EINVAL;
> @@ -170,7 +170,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",
> ppc_inst_val(op));
>  		return -EINVAL;
>  	}
> @@ -200,7 +201,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,
> ppc_inst_val(op));
>  		return -EINVAL;
>  	}
> @@ -497,7 +498,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> unsigned int op1)
>  	 * The load offset is different depending on the ABI. For simplicity
>  	 * just mask it out when doing the compare.
>  	 */
> -	if ((op0 != ppc_inst(0x48000008)) || (ppc_inst_val(op1) & 0xffff0000)
> != 0xe8410000)
> +	if ((!ppc_inst_equal(op0), ppc_inst(0x48000008)) || (ppc_inst_val(op1)
> & 0xffff0000) != 0xe8410000)
>  		return 0;
>  	return 1;
>  }
> @@ -506,7 +507,7 @@ static int
>  expected_nop_sequence(void *ip, unsigned int op0, unsigned int 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;
>  }
> @@ -589,7 +590,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;
>  	}
> @@ -646,7 +647,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,
> ppc_inst_val(op));
>  		return -EINVAL;
>  	}
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index 3f88d2a4400c..33654c6334a9 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -478,7 +478,7 @@ static void __init test_branch_iform(void)
>  	/* Check flags are masked correctly */
>  	err = create_branch(&instr, &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)
> @@ -563,7 +563,7 @@ static void __init test_branch_bform(void)
>  	/* Check flags are masked correctly */
>  	err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
>  	check(instr_is_branch_to_addr(&instr, addr));
> -	check(instr == ppc_inst(0x43FF0000));
> +	check(ppc_inst_equal(instr, ppc_inst(0x43FF0000)));
>  }
>  
>  static void __init test_translate_branch(void)
> @@ -597,7 +597,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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(*q, ppc_inst(0x4a000000)));
>  
>  	/* Maximum positive case, move x to x - 32 MB + 4 */
>  	p = buf + 0x2000000;
> @@ -608,7 +608,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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(*q, ppc_inst(0x49fffffc)));
>  
>  	/* Jump to x + 16 MB moved to x + 20 MB */
>  	p = buf;
> @@ -654,7 +654,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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(*q, ppc_inst(0x43ff8000)));
>  
>  	/* Maximum positive case, move x to x - 32 KB + 4 */
>  	p = buf + 0x8000;
> @@ -666,7 +666,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	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(*q, ppc_inst(0x43ff7ffc)));
>  
>  	/* Jump to x + 12 KB moved to x + 20 KB */
>  	p = buf;
> diff --git a/arch/powerpc/lib/test_emulate_step.c
> b/arch/powerpc/lib/test_emulate_step.c
> index 60f7eb24d742..16387a9bfda0 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -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_val(instr))


This change should go in to below patch,

[PATCH v5 06/21] powerpc: Use an accessor for instructions

-- Bala


>  		return -EINVAL;
>  
>  	/* Patch the NOP with the actual instruction */
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 3c1fb46bfacf..f6c87d3d53ea 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -950,7 +950,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(
>  			(unsigned int *)bp->address, bp->instr[0]) != 0)
>  			printf("Couldn't remove breakpoint at %lx\n",
> @@ -2860,7 +2860,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;


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

* Re: [PATCH v5 07/21] powerpc: Use a function for byte swapping instructions
  2020-04-06  8:09 ` [PATCH v5 07/21] powerpc: Use a function for byte swapping instructions Jordan Niethe
@ 2020-04-07  7:42   ` Balamuruhan S
  0 siblings, 0 replies; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07  7:42 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> Use a function for byte swapping instructions in preparation of a more
> complicated instruction type.

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

> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>  arch/powerpc/include/asm/inst.h | 5 +++++
>  arch/powerpc/kernel/align.c     | 2 +-
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> index 15f570bef936..78eb1481f1f6 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -18,4 +18,9 @@ static inline int ppc_inst_opcode(u32 x)
>  	return x >> 26;
>  }
>  
> +static inline u32 ppc_inst_swab(u32 x)
> +{
> +	return ppc_inst(swab32(ppc_inst_val(x)));
> +}
> +
>  #endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index a83d32c6513d..46870cf6a6dc 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -310,7 +310,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_swab(instr);
>  	}
>  
>  #ifdef CONFIG_SPE


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

* Re: [PATCH v5 04/21] powerpc: Use a macro for creating instructions from u32s
  2020-04-07  6:40   ` Balamuruhan S
@ 2020-04-07  8:27     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-07  8:27 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Tue, Apr 7, 2020 at 4:40 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > In preparation for instructions having a more complex data type start
> > using a macro, ppc_inst(), for making an instruction out of a u32.  A
> > macro is used so that instructions can be used as initializer elements.
> > 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
> > v5: - Rename PPC_INST() -> ppc_inst().
> >     - Use on epapr_paravirt.c, kgdb.c
> > ---
> >  arch/powerpc/include/asm/code-patching.h |  3 +-
> >  arch/powerpc/include/asm/inst.h          | 11 +++++
> >  arch/powerpc/kernel/align.c              |  1 +
> >  arch/powerpc/kernel/epapr_paravirt.c     |  5 ++-
> >  arch/powerpc/kernel/hw_breakpoint.c      |  3 +-
> >  arch/powerpc/kernel/jump_label.c         |  3 +-
> >  arch/powerpc/kernel/kgdb.c               |  5 ++-
> >  arch/powerpc/kernel/kprobes.c            |  5 ++-
> >  arch/powerpc/kernel/module_64.c          |  3 +-
> >  arch/powerpc/kernel/optprobes.c          | 31 ++++++-------
> >  arch/powerpc/kernel/security.c           |  9 ++--
> >  arch/powerpc/kernel/trace/ftrace.c       | 25 ++++++-----
> >  arch/powerpc/kernel/uprobes.c            |  1 +
> >  arch/powerpc/kvm/emulate_loadstore.c     |  2 +-
> >  arch/powerpc/lib/code-patching.c         | 57 ++++++++++++------------
> >  arch/powerpc/lib/feature-fixups.c        | 39 ++++++++--------
> >  arch/powerpc/lib/test_emulate_step.c     | 39 ++++++++--------
> >  arch/powerpc/xmon/xmon.c                 |  7 +--
> >  18 files changed, 138 insertions(+), 111 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 351dda7215b6..48e021957ee5 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);
> > @@ -48,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/include/asm/inst.h
> > b/arch/powerpc/include/asm/inst.h
> > new file mode 100644
> > index 000000000000..5298ba33b6e5
> > --- /dev/null
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -0,0 +1,11 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +#ifndef _ASM_INST_H
> > +#define _ASM_INST_H
> > +
> > +/*
> > + * Instruction data type for POWER
> > + */
> > +
> > +#define ppc_inst(x) (x)
> > +
> > +#endif /* _ASM_INST_H */
> > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > index 92045ed64976..86e9bf62f18c 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -24,6 +24,7 @@
> >  #include <asm/disassemble.h>
> >  #include <asm/cpu_has_feature.h>
> >  #include <asm/sstep.h>
> > +#include <asm/inst.h>
> >
> >  struct aligninfo {
> >       unsigned char len;
> > diff --git a/arch/powerpc/kernel/epapr_paravirt.c
> > b/arch/powerpc/kernel/epapr_paravirt.c
> > index 9d32158ce36f..c53e863fb484 100644
> > --- a/arch/powerpc/kernel/epapr_paravirt.c
> > +++ b/arch/powerpc/kernel/epapr_paravirt.c
> > @@ -11,6 +11,7 @@
> >  #include <asm/cacheflush.h>
> >  #include <asm/code-patching.h>
> >  #include <asm/machdep.h>
> > +#include <asm/inst.h>
> >
> >  #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
> >  extern void epapr_ev_idle(void);
> > @@ -37,9 +38,9 @@ static int __init early_init_dt_scan_epapr(unsigned long
> > node,
> >
> >       for (i = 0; i < (len / 4); i++) {
> >               u32 inst = be32_to_cpu(insts[i]);
> > -             patch_instruction(epapr_hypercall_start + i, inst);
> > +             patch_instruction(epapr_hypercall_start + i, ppc_inst(inst));
> >  #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
> > -             patch_instruction(epapr_ev_idle_start + i, inst);
> > +             patch_instruction(epapr_ev_idle_start + i, ppc_inst(inst));
>
>
> can we do it once while assigning inst ?
>
> u32 inst = ppc_inst(be32_to_cpu(insts[i]));
Yeah that would be better.
>
> -- Bala
>
> >  #endif
> >       }
> >
> > diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> > b/arch/powerpc/kernel/hw_breakpoint.c
> > index 2462cd7c565c..79f51f182a83 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;
> > +     unsigned int 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..daa4afce7ec8 100644
> > --- a/arch/powerpc/kernel/jump_label.c
> > +++ b/arch/powerpc/kernel/jump_label.c
> > @@ -6,6 +6,7 @@
> >  #include <linux/kernel.h>
> >  #include <linux/jump_label.h>
> >  #include <asm/code-patching.h>
> > +#include <asm/inst.h>
> >
> >  void arch_jump_label_transform(struct jump_entry *entry,
> >                              enum jump_label_type type)
> > @@ -15,5 +16,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/kgdb.c b/arch/powerpc/kernel/kgdb.c
> > index 7dd55eb1259d..a6b38a19133f 100644
> > --- a/arch/powerpc/kernel/kgdb.c
> > +++ b/arch/powerpc/kernel/kgdb.c
> > @@ -26,6 +26,7 @@
> >  #include <asm/debug.h>
> >  #include <asm/code-patching.h>
> >  #include <linux/slab.h>
> > +#include <asm/inst.h>
> >
> >  /*
> >   * This table contains the mapping between PowerPC hardware trap types, and
> > @@ -424,7 +425,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
> >       if (err)
> >               return err;
> >
> > -     err = patch_instruction(addr, BREAK_INSTR);
> > +     err = patch_instruction(addr, ppc_inst(BREAK_INSTR));
> >       if (err)
> >               return -EFAULT;
> >
> > @@ -439,7 +440,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
> >       unsigned int instr = *(unsigned int *)bpt->saved_instr;
> >       unsigned int *addr = (unsigned int *)bpt->bpt_addr;
> >
> > -     err = patch_instruction(addr, instr);
> > +     err = patch_instruction(addr, ppc_inst(instr));
> >       if (err)
> >               return -EFAULT;
> >
> > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> > index 2d27ec4feee4..a1a3686f41c6 100644
> > --- a/arch/powerpc/kernel/kprobes.c
> > +++ b/arch/powerpc/kernel/kprobes.c
> > @@ -23,6 +23,7 @@
> >  #include <asm/cacheflush.h>
> >  #include <asm/sstep.h>
> >  #include <asm/sections.h>
> > +#include <asm/inst.h>
> >  #include <linux/uaccess.h>
> >
> >  DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
> > @@ -138,13 +139,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..7fd6b29edcb2 100644
> > --- a/arch/powerpc/kernel/module_64.c
> > +++ b/arch/powerpc/kernel/module_64.c
> > @@ -20,6 +20,7 @@
> >  #include <linux/sort.h>
> >  #include <asm/setup.h>
> >  #include <asm/sections.h>
> > +#include <asm/inst.h>
> >
> >  /* FIXME: We don't do .init separately.  To do this, we'd need to have
> >     a separate r2 value in the init and core section, and stub between
> > @@ -506,7 +507,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 445b3dad82dc..3b33ebf18859 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -16,6 +16,7 @@
> >  #include <asm/code-patching.h>
> >  #include <asm/sstep.h>
> >  #include <asm/ppc-opcode.h>
> > +#include <asm/inst.h>
> >
> >  #define TMPL_CALL_HDLR_IDX   \
> >       (optprobe_template_call_handler - optprobe_template_entry)
> > @@ -147,13 +148,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 +164,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 +231,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..81a288b1a603 100644
> > --- a/arch/powerpc/kernel/security.c
> > +++ b/arch/powerpc/kernel/security.c
> > @@ -14,6 +14,7 @@
> >  #include <asm/debugfs.h>
> >  #include <asm/security_features.h>
> >  #include <asm/setup.h>
> > +#include <asm/inst.h>
> >
> >
> >  u64 powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
> > @@ -403,9 +404,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 +429,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 +440,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 4dcb379133f8..47233e671c18 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
> > @@ -161,7 +162,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 +170,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 +189,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 +200,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 +276,7 @@ __ftrace_make_nop(struct module *mod,
> >               return -EINVAL;
> >       }
> >
> > -     op = PPC_INST_NOP;
> > +     op = ppc_inst(PPC_INST_NOP);
> >
> >       if (patch_instruction((unsigned int *)ip, op))
> >               return -EPERM;
> > @@ -420,7 +421,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((unsigned int *)ip, ppc_inst(PPC_INST_NOP))) {
> >               pr_err("Patching NOP failed.\n");
> >               return -EPERM;
> >       }
> > @@ -442,7 +443,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);
> > @@ -496,7 +497,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> > unsigned int 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 != ppc_inst(0x48000008)) || ((op1 & 0xffff0000) !=
> > 0xe8410000))
> >               return 0;
> >       return 1;
> >  }
> > @@ -505,7 +506,7 @@ static int
> >  expected_nop_sequence(void *ip, unsigned int op0, unsigned int 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;
> >  }
> > @@ -588,7 +589,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;
> >       }
> > @@ -645,7 +646,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;
> >       }
> > @@ -676,7 +677,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/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> > index 1cfef0e5fec5..31c870287f2b 100644
> > --- a/arch/powerpc/kernel/uprobes.c
> > +++ b/arch/powerpc/kernel/uprobes.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/kdebug.h>
> >
> >  #include <asm/sstep.h>
> > +#include <asm/inst.h>
> >
> >  #define UPROBE_TRAP_NR       UINT_MAX
> >
> > diff --git a/arch/powerpc/kvm/emulate_loadstore.c
> > b/arch/powerpc/kvm/emulate_loadstore.c
> > index 1139bc56e004..135d0e686622 100644
> > --- a/arch/powerpc/kvm/emulate_loadstore.c
> > +++ b/arch/powerpc/kvm/emulate_loadstore.c
> > @@ -95,7 +95,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 4af564aeedf1..fdf0d6ea3575 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -17,6 +17,7 @@
> >  #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)
> > @@ -413,37 +414,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 */
> > @@ -477,7 +478,7 @@ static void __init test_branch_iform(void)
> >       /* Check flags are masked correctly */
> >       err = create_branch(&instr, &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)
> > @@ -504,28 +505,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 */
> > @@ -562,7 +563,7 @@ static void __init test_branch_bform(void)
> >       /* Check flags are masked correctly */
> >       err = create_cond_branch(&instr, iptr, addr, 0xFFFFFFFC);
> >       check(instr_is_branch_to_addr(&instr, addr));
> > -     check(instr == 0x43FF0000);
> > +     check(instr == ppc_inst(0x43FF0000));
> >  }
> >
> >  static void __init test_translate_branch(void)
> > @@ -596,7 +597,7 @@ static void __init test_translate_branch(void)
> >       patch_instruction(q, instr);
> >       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;
> > @@ -607,7 +608,7 @@ static void __init test_translate_branch(void)
> >       patch_instruction(q, instr);
> >       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;
> > @@ -653,7 +654,7 @@ static void __init test_translate_branch(void)
> >       patch_instruction(q, instr);
> >       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;
> > @@ -665,7 +666,7 @@ static void __init test_translate_branch(void)
> >       patch_instruction(q, instr);
> >       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 b129d7b4e7dd..6e7479b8887a 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;
> > @@ -89,7 +90,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;
> >  }
> > @@ -146,15 +147,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,
> > @@ -207,12 +208,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" :
> > @@ -260,9 +261,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,
> > @@ -295,7 +296,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);
> > @@ -338,8 +339,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);
> > @@ -353,7 +354,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));
> >       }
> >  }
> >
> > @@ -382,7 +383,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));
> >       }
> >  }
> >
> > @@ -400,7 +401,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 42347067739c..88b17226a493 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 049375206510..68ecb39dd9cc 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>
> > @@ -949,7 +950,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(
> >                       (unsigned int *)bp->address, bp->instr[0]) != 0)
> >                       printf("Couldn't remove breakpoint at %lx\n",
> > @@ -2845,7 +2846,7 @@ generic_inst_dump(unsigned long adr, long count, int
> > praddr,
> >  {
> >       int nr, dotted;
> >       unsigned long first_adr;
> > -     unsigned int inst, last_inst = 0;
> > +     unsigned int inst, last_inst = ppc_inst(0);
> >       unsigned char val[4];
> >
> >       dotted = 0;
> > @@ -2858,7 +2859,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");
>

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

* Re: [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code
  2020-04-07  7:04   ` Balamuruhan S
@ 2020-04-07  8:32     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-07  8:32 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Tue, Apr 7, 2020 at 5:05 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, 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.
>
> vecemu.c and sstep.c will need ppc_inst_opcode().
Sorry, I forget you pointed those files out before. I added other
things to them but then I forgot to add this. Will do for next time.
>
> -- Bala
>
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v4: New to series
> > ---
> >  arch/powerpc/include/asm/inst.h  | 5 +++++
> >  arch/powerpc/kernel/align.c      | 2 +-
> >  arch/powerpc/lib/code-patching.c | 4 ++--
> >  3 files changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/inst.h
> > b/arch/powerpc/include/asm/inst.h
> > index 5298ba33b6e5..93959016fe4b 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -8,4 +8,9 @@
> >
> >  #define ppc_inst(x) (x)
> >
> > +static inline int ppc_inst_opcode(u32 x)
> > +{
> > +     return x >> 26;
> > +}
> > +
> >  #endif /* _ASM_INST_H */
> > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > index 86e9bf62f18c..691013aa9f3c 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -314,7 +314,7 @@ int fix_alignment(struct pt_regs *regs)
> >       }
> >
> >  #ifdef CONFIG_SPE
> > -     if ((instr >> 26) == 0x4) {
> > +     if (ppc_inst_opcode(instr) == 0x4) {
> >               int reg = (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 fdf0d6ea3575..099a515202aa 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -231,7 +231,7 @@ bool is_offset_in_branch_range(long offset)
> >   */
> >  bool is_conditional_branch(unsigned int instr)
> >  {
> > -     unsigned int opcode = instr >> 26;
> > +     unsigned int opcode = ppc_inst_opcode(instr);
> >
> >       if (opcode == 16)       /* bc, bca, bcl, bcla */
> >               return true;
> > @@ -289,7 +289,7 @@ int create_cond_branch(unsigned int *instr, const
> > unsigned int *addr,
> >
> >  static unsigned int branch_opcode(unsigned int instr)
> >  {
> > -     return (instr >> 26) & 0x3F;
> > +     return ppc_inst_opcode(instr) & 0x3F;
> >  }
> >
> >  static int instr_is_branch_iform(unsigned int instr)
>

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

* Re: [PATCH v5 09/21] powerpc: Use a datatype for instructions
  2020-04-06  8:09 ` [PATCH v5 09/21] powerpc: Use a datatype for instructions Jordan Niethe
  2020-04-06 10:34     ` kbuild test robot
  2020-04-06 10:35     ` kbuild test robot
@ 2020-04-07 10:30   ` Balamuruhan S
  2020-04-08  2:11     ` Jordan Niethe
  2 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07 10:30 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, 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>
> ---
> v4: New to series
> v5: Add to epapr_paravirt.c, kgdb.c
> ---
>  arch/powerpc/include/asm/code-patching.h | 32 ++++-----
>  arch/powerpc/include/asm/inst.h          | 20 +++---
>  arch/powerpc/include/asm/sstep.h         |  5 +-
>  arch/powerpc/include/asm/uprobes.h       |  5 +-
>  arch/powerpc/kernel/align.c              |  4 +-
>  arch/powerpc/kernel/epapr_paravirt.c     |  4 +-
>  arch/powerpc/kernel/hw_breakpoint.c      |  4 +-
>  arch/powerpc/kernel/jump_label.c         |  2 +-
>  arch/powerpc/kernel/kgdb.c               |  4 +-
>  arch/powerpc/kernel/kprobes.c            |  8 +--
>  arch/powerpc/kernel/mce_power.c          |  5 +-
>  arch/powerpc/kernel/optprobes.c          | 40 ++++++------
>  arch/powerpc/kernel/setup_32.c           |  2 +-
>  arch/powerpc/kernel/trace/ftrace.c       | 83 ++++++++++++------------
>  arch/powerpc/kernel/vecemu.c             |  5 +-
>  arch/powerpc/lib/code-patching.c         | 69 ++++++++++----------
>  arch/powerpc/lib/feature-fixups.c        | 48 +++++++-------
>  arch/powerpc/lib/sstep.c                 |  4 +-
>  arch/powerpc/lib/test_emulate_step.c     |  9 +--
>  arch/powerpc/perf/core-book3s.c          |  4 +-
>  arch/powerpc/xmon/xmon.c                 | 24 +++----
>  21 files changed, 196 insertions(+), 185 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h
> b/arch/powerpc/include/asm/code-patching.h
> index 48e021957ee5..eacc9102c251 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -23,33 +23,33 @@
>  #define BRANCH_ABSOLUTE	0x2
>  
>  bool is_offset_in_branch_range(long offset);
> -int create_branch(unsigned int *instr, const unsigned int *addr,
> +int create_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
>  		  unsigned long target, int flags);
> -int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> +int create_cond_branch(struct ppc_inst *instr, const struct 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(struct ppc_inst *addr, unsigned long target, int flags);
> +int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
> +int raw_patch_instruction(struct ppc_inst *addr, struct 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, struct ppc_inst instr)
>  {
> -	return patch_instruction((unsigned int *)patch_site_addr(site), instr);
> +	return patch_instruction((struct 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((struct ppc_inst *)patch_site_addr(site), target,
> flags);
>  }
>  
>  static inline int modify_instruction(unsigned int *addr, unsigned int clr,
>  				     unsigned int set)
>  {
> -	return patch_instruction(addr, ppc_inst((*addr & ~clr) | set));
> +	return patch_instruction((struct ppc_inst *)addr, ppc_inst((*addr &
> ~clr) | set));
>  }
>  
>  static inline int modify_instruction_site(s32 *site, unsigned int clr,
> unsigned int set)
> @@ -57,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);
> -int translate_branch(unsigned int *instr, const unsigned int *dest,
> -		     const unsigned int *src);
> -extern bool is_conditional_branch(unsigned int instr);
> +int instr_is_relative_branch(struct ppc_inst instr);
> +int instr_is_relative_link_branch(struct ppc_inst instr);
> +int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long
> addr);
> +unsigned long branch_target(const struct ppc_inst *instr);
> +int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
> +		     const struct ppc_inst *src);
> +extern bool is_conditional_branch(struct 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
> index 54ee46b0a7c9..a71decf5f871 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -6,26 +6,30 @@
>   * Instruction data type for POWER
>   */
>  
> -#define ppc_inst(x) (x)
> +struct ppc_inst {
> +        u32 val;
> +} __packed;
>  
> -static inline u32 ppc_inst_val(u32 x)
> +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> +
> +static inline u32 ppc_inst_val(struct ppc_inst x)
>  {
> -	return x;
> +	return x.val;
>  }
>  
> -static inline int ppc_inst_opcode(u32 x)
> +static inline int ppc_inst_opcode(struct ppc_inst x)
>  {
> -	return x >> 26;
> +	return x.val >> 26;
>  }
>  
> -static inline u32 ppc_inst_swab(u32 x)
> +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
>  {
>  	return ppc_inst(swab32(ppc_inst_val(x)));
>  }
>  
> -static inline bool ppc_inst_equal(u32 x, u32 y)
> +static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
>  {
> -	return x == y;
> +	return !memcmp(&x, &y, sizeof(struct ppc_inst));
>  }
>  
>  #endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/include/asm/sstep.h
> b/arch/powerpc/include/asm/sstep.h
> index 26d729562fe2..c3ce903ac488 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);
> +			 struct 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, struct ppc_inst instr);
>  
>  /*
>   * Emulate a load or store instruction by reading/writing the
> diff --git a/arch/powerpc/include/asm/uprobes.h
> b/arch/powerpc/include/asm/uprobes.h
> index 2bbdf27d09b5..7e3b329ba2d3 100644
> --- a/arch/powerpc/include/asm/uprobes.h
> +++ b/arch/powerpc/include/asm/uprobes.h
> @@ -11,6 +11,7 @@
>  
>  #include <linux/notifier.h>
>  #include <asm/probes.h>
> +#include <asm/inst.h>
>  
>  typedef ppc_opcode_t uprobe_opcode_t;
>  
> @@ -23,8 +24,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
>  
>  struct arch_uprobe {
>  	union {
> -		u32	insn;
> -		u32	ixol;
> +		struct ppc_inst	insn;
> +		struct ppc_inst	ixol;
>  	};
>  };
>  
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index 46870cf6a6dc..66a6d1de7799 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -294,7 +294,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int
> reg,
>  
>  int fix_alignment(struct pt_regs *regs)
>  {
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  	struct instruction_op op;
>  	int r, type;
>  
> @@ -304,7 +304,7 @@ 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.val, (unsigned int __user *)regs->nip)))


don't we have to use the helper `ppc_inst_val()` here to retrieve instr.val ?

I see couple of other places we directly retrieve as instr.val.
if we need to change it, then all of them should go to patch 6,
[PATCH v5 06/21] powerpc: Use an accessor for instructions


>  		return -EFAULT;
>  	if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
>  		/* We don't handle PPC little-endian any more... */
> diff --git a/arch/powerpc/kernel/epapr_paravirt.c
> b/arch/powerpc/kernel/epapr_paravirt.c
> index c53e863fb484..c42aa3926632 100644
> --- a/arch/powerpc/kernel/epapr_paravirt.c
> +++ b/arch/powerpc/kernel/epapr_paravirt.c
> @@ -38,9 +38,9 @@ static int __init early_init_dt_scan_epapr(unsigned long
> node,
>  
>  	for (i = 0; i < (len / 4); i++) {
>  		u32 inst = be32_to_cpu(insts[i]);
> -		patch_instruction(epapr_hypercall_start + i, ppc_inst(inst));
> +		patch_instruction((struct ppc_inst *)(epapr_hypercall_start +
> i), ppc_inst(inst));
>  #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
> -		patch_instruction(epapr_ev_idle_start + i, ppc_inst(inst));
> +		patch_instruction((struct ppc_inst *)(epapr_ev_idle_start + i),
> ppc_inst(inst));
>  #endif
>  	}
>  
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> b/arch/powerpc/kernel/hw_breakpoint.c
> index 79f51f182a83..542f65ccf68b 100644
> --- a/arch/powerpc/kernel/hw_breakpoint.c
> +++ b/arch/powerpc/kernel/hw_breakpoint.c
> @@ -244,12 +244,12 @@ 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 = ppc_inst(0);
> +	struct ppc_inst instr = ppc_inst(0);
>  	int ret, type, size;
>  	struct instruction_op op;
>  	unsigned long addr = info->address;
>  
> -	if (__get_user_inatomic(instr, (unsigned int *)regs->nip))
> +	if (__get_user_inatomic(instr.val, (unsigned int *)regs->nip))


[...] reference to above


>  		goto fail;
>  
>  	ret = analyse_instr(&op, regs, instr);
> diff --git a/arch/powerpc/kernel/jump_label.c
> b/arch/powerpc/kernel/jump_label.c
> index daa4afce7ec8..144858027fa3 100644
> --- a/arch/powerpc/kernel/jump_label.c
> +++ b/arch/powerpc/kernel/jump_label.c
> @@ -11,7 +11,7 @@
>  void arch_jump_label_transform(struct jump_entry *entry,
>  			       enum jump_label_type type)
>  {
> -	u32 *addr = (u32 *)(unsigned long)entry->code;
> +	struct ppc_inst *addr = (struct ppc_inst *)(unsigned long)entry->code;
>  
>  	if (type == JUMP_LABEL_JMP)
>  		patch_branch(addr, entry->target, 0);
> diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
> index a6b38a19133f..652b2852bea3 100644
> --- a/arch/powerpc/kernel/kgdb.c
> +++ b/arch/powerpc/kernel/kgdb.c
> @@ -419,7 +419,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
>  {
>  	int err;
>  	unsigned int instr;
> -	unsigned int *addr = (unsigned int *)bpt->bpt_addr;
> +	struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
>  
>  	err = probe_kernel_address(addr, instr);
>  	if (err)
> @@ -438,7 +438,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
>  {
>  	int err;
>  	unsigned int instr = *(unsigned int *)bpt->saved_instr;
> -	unsigned int *addr = (unsigned int *)bpt->bpt_addr;
> +	struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
>  
>  	err = patch_instruction(addr, ppc_inst(instr));
>  	if (err)
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 8420b1944164..9ed996cb0589 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name,
> unsigned int offset)
>  int arch_prepare_kprobe(struct kprobe *p)
>  {
>  	int ret = 0;
> -	kprobe_opcode_t insn = *p->addr;
> +	struct ppc_inst insn = *(struct ppc_inst *)p->addr;
>  
>  	if ((unsigned long)p->addr & 0x03) {
>  		printk("Attempt to register kprobe at an unaligned address\n");
> @@ -139,13 +139,13 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
>  
>  void arch_arm_kprobe(struct kprobe *p)
>  {
> -	patch_instruction(p->addr, ppc_inst(BREAKPOINT_INSTRUCTION));
> +	patch_instruction((struct ppc_inst *)p->addr,
> ppc_inst(BREAKPOINT_INSTRUCTION));
>  }
>  NOKPROBE_SYMBOL(arch_arm_kprobe);
>  
>  void arch_disarm_kprobe(struct kprobe *p)
>  {
> -	patch_instruction(p->addr, ppc_inst(p->opcode));
> +	patch_instruction((struct ppc_inst *)p->addr, ppc_inst(p->opcode));
>  }
>  NOKPROBE_SYMBOL(arch_disarm_kprobe);
>  
> @@ -217,7 +217,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;
> +	struct ppc_inst insn = *(struct 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 1cbf7f1a4e3d..7118b46a6543 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;
> +	struct 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 = *(struct 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 3b33ebf18859..b61bbcee84f4 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -100,8 +100,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(*(struct ppc_inst *)p->ainsn.insn) &&
> +			analyse_instr(&op, &regs, *(struct ppc_inst *)p-
> >ainsn.insn) == 1) {
>  		emulate_update_regs(&regs, &op);
>  		nip = regs.nip;
>  	}
> @@ -148,12 +148,12 @@ 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(PPC_INST_ADDIS | ___PPC_RT(4) |
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> ___PPC_RT(4) |
>  			  ((val >> 16) & 0xffff)));
>  	addr++;
>  
>  	/* ori r4,r4,(insn)@l */
> -	patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(4) |
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> ___PPC_RA(4) |
>  			  ___PPC_RS(4) | (val & 0xffff)));
>  }
>  
> @@ -164,34 +164,34 @@ 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(PPC_INST_ADDIS | ___PPC_RT(3) |
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> ___PPC_RT(3) |
>  			  ((val >> 48) & 0xffff)));
>  	addr++;
>  
>  	/* ori r3,r3,(op)@higher */
> -	patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(3) |
> +	patch_instruction((struct ppc_inst *)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(PPC_INST_RLDICR | ___PPC_RA(3) |
> +	patch_instruction((struct ppc_inst *)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(PPC_INST_ORIS | ___PPC_RA(3) |
> +	patch_instruction((struct ppc_inst *)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(PPC_INST_ORI | ___PPC_RA(3) |
> +	patch_instruction((struct ppc_inst *)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)
>  {
> -	kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
> -	kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
> +	struct 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;
> @@ -231,7 +231,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,
> ppc_inst(*(optprobe_template_entry + i)));
> +		rc = patch_instruction((struct ppc_inst *)(buff + i),
> ppc_inst(*(optprobe_template_entry + i)));
>  		if (rc < 0)
>  			goto error;
>  	}
> @@ -253,20 +253,20 @@ int arch_prepare_optimized_kprobe(struct
> optimized_kprobe *op, struct kprobe *p)
>  	}
>  
>  	rc = create_branch(&branch_op_callback,
> -			   (unsigned int *)buff + TMPL_CALL_HDLR_IDX,
> +			   (struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX),
>  			   (unsigned long)op_callback_addr,
>  			   BRANCH_SET_LINK);
>  
>  	rc |= create_branch(&branch_emulate_step,
> -			    (unsigned int *)buff + TMPL_EMULATE_IDX,
> +			    (struct ppc_inst *)(buff + TMPL_EMULATE_IDX),
>  			    (unsigned long)emulate_step_addr,
>  			    BRANCH_SET_LINK);
>  
>  	if (rc)
>  		goto error;
>  
> -	patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
> -	patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step);
> +	patch_instruction((struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX),
> branch_op_callback);
> +	patch_instruction((struct ppc_inst *)(buff + TMPL_EMULATE_IDX),
> branch_emulate_step);
>  
>  	/*
>  	 * 3. load instruction to be emulated into relevant register, and
> @@ -276,7 +276,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe
> *op, struct kprobe *p)
>  	/*
>  	 * 4. branch back from trampoline
>  	 */
> -	patch_branch(buff + TMPL_RET_IDX, (unsigned long)nip, 0);
> +	patch_branch((void *)(buff + TMPL_RET_IDX), (unsigned long)nip, 0);


why do we cast it differently here ?


>  
>  	flush_icache_range((unsigned long)buff,
>  			   (unsigned long)(&buff[TMPL_END_IDX]));
> @@ -308,7 +308,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe
> *op)
>  
>  void arch_optimize_kprobes(struct list_head *oplist)
>  {
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  	struct optimized_kprobe *op;
>  	struct optimized_kprobe *tmp;
>  
> @@ -320,9 +320,9 @@ void arch_optimize_kprobes(struct list_head *oplist)
>  		memcpy(op->optinsn.copied_insn, op->kp.addr,
>  					       RELATIVEJUMP_SIZE);
>  		create_branch(&instr,
> -			      (unsigned int *)op->kp.addr,
> +			      (struct ppc_inst *)op->kp.addr,
>  			      (unsigned long)op->optinsn.insn, 0);
> -		patch_instruction(op->kp.addr, instr);
> +		patch_instruction((struct ppc_inst *)op->kp.addr, instr);
>  		list_del_init(&op->list);
>  	}
>  }
> diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
> index c1bdd462c5c0..989809e58234 100644
> --- a/arch/powerpc/kernel/setup_32.c
> +++ b/arch/powerpc/kernel/setup_32.c
> @@ -76,7 +76,7 @@ EXPORT_SYMBOL(DMA_MODE_WRITE);
>  notrace void __init machine_init(u64 dt_ptr)
>  {
>  	unsigned int *addr = (unsigned int
> *)patch_site_addr(&patch__memset_nocache);
> -	unsigned long insn;
> +	struct ppc_inst insn;
>  
>  	/* Configure static keys first, now that we're relocated. */
>  	setup_feature_keys();
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c
> index 784b5746cc55..442c62fb68ff 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -41,23 +41,23 @@
>  #define	NUM_FTRACE_TRAMPS	8
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
>  
> -static unsigned int
> +static struct ppc_inst
>  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
>  {
> -	unsigned int op;
> +	struct ppc_inst op;
>  
>  	addr = ppc_function_entry((void *)addr);
>  
>  	/* if (link) set op to 'bl' else 'b' */
> -	create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
> +	create_branch(&op, (struct 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, struct ppc_inst old, struct ppc_inst
> new)
>  {
> -	unsigned int replaced;
> +	struct ppc_inst replaced;
>  
>  	/*
>  	 * Note:
> @@ -79,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((struct ppc_inst *)ip, new))
>  		return -EPERM;
>  
>  	return 0;
> @@ -90,24 +90,24 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> unsigned int new)
>   */
>  static int test_24bit_addr(unsigned long ip, unsigned long addr)
>  {
> -	unsigned int op;
> +	struct ppc_inst op;
>  	addr = ppc_function_entry((void *)addr);
>  
>  	/* use the create_branch to verify that this offset can be branched */
> -	return create_branch(&op, (unsigned int *)ip, addr, 0) == 0;
> +	return create_branch(&op, (struct ppc_inst *)ip, addr, 0) == 0;
>  }
>  
> -static int is_bl_op(unsigned int op)
> +static int is_bl_op(struct ppc_inst op)
>  {
>  	return (ppc_inst_val(op) & 0xfc000003) == 0x48000001;
>  }
>  
> -static int is_b_op(unsigned int op)
> +static int is_b_op(struct ppc_inst op)
>  {
>  	return (ppc_inst_val(op) & 0xfc000003) == 0x48000000;
>  }
>  
> -static unsigned long find_bl_target(unsigned long ip, unsigned int op)
> +static unsigned long find_bl_target(unsigned long ip, struct ppc_inst op)
>  {
>  	int offset;
>  
> @@ -127,7 +127,7 @@ __ftrace_make_nop(struct module *mod,
>  {
>  	unsigned long entry, ptr, tramp;
>  	unsigned long ip = rec->ip;
> -	unsigned int op, pop;
> +	struct ppc_inst op, pop;
>  
>  	/* read where this goes */
>  	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> @@ -207,7 +207,7 @@ __ftrace_make_nop(struct module *mod,
>  	}
>  #endif /* CONFIG_MPROFILE_KERNEL */
>  
> -	if (patch_instruction((unsigned int *)ip, pop)) {
> +	if (patch_instruction((struct ppc_inst *)ip, pop)) {
>  		pr_err("Patching NOP failed.\n");
>  		return -EPERM;
>  	}
> @@ -220,7 +220,7 @@ static int
>  __ftrace_make_nop(struct module *mod,
>  		  struct dyn_ftrace *rec, unsigned long addr)
>  {
> -	unsigned int op;
> +	struct ppc_inst op;
>  	unsigned int jmp[4];
>  	unsigned long ip = rec->ip;
>  	unsigned long tramp;
> @@ -279,7 +279,7 @@ __ftrace_make_nop(struct module *mod,
>  
>  	op = ppc_inst(PPC_INST_NOP);
>  
> -	if (patch_instruction((unsigned int *)ip, op))
> +	if (patch_instruction((struct ppc_inst *)ip, op))
>  		return -EPERM;
>  
>  	return 0;
> @@ -290,7 +290,7 @@ __ftrace_make_nop(struct module *mod,
>  static unsigned long find_ftrace_tramp(unsigned long ip)
>  {
>  	int i;
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  
>  	/*
>  	 * We have the compiler generated long_branch tramps at the end
> @@ -327,9 +327,10 @@ static int add_ftrace_tramp(unsigned long tramp)
>   */
>  static int setup_mcount_compiler_tramp(unsigned long tramp)
>  {
> -	int i, op;
> +	int i;
> +	struct ppc_inst op;
>  	unsigned long ptr;
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
>  
>  	/* Is this a known long jump tramp? */
> @@ -378,7 +379,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> tramp)
>  		return -1;
>  	}
>  
> -	if (patch_branch((unsigned int *)tramp, ptr, 0)) {
> +	if (patch_branch((struct ppc_inst *)tramp, ptr, 0)) {
>  		pr_debug("REL24 out of range!\n");
>  		return -1;
>  	}
> @@ -394,7 +395,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;
> +	struct ppc_inst op;
>  
>  	/* Read where this goes */
>  	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> @@ -422,7 +423,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  		}
>  	}
>  
> -	if (patch_instruction((unsigned int *)ip, ppc_inst(PPC_INST_NOP))) {
> +	if (patch_instruction((struct ppc_inst *)ip, ppc_inst(PPC_INST_NOP))) {
>  		pr_err("Patching NOP failed.\n");
>  		return -EPERM;
>  	}
> @@ -434,7 +435,7 @@ int ftrace_make_nop(struct module *mod,
>  		    struct dyn_ftrace *rec, unsigned long addr)
>  {
>  	unsigned long ip = rec->ip;
> -	unsigned int old, new;
> +	struct ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -487,7 +488,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, struct ppc_inst op0, struct ppc_inst op1)
>  {
>  	/*
>  	 * We expect to see:
> @@ -504,7 +505,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> unsigned int op1)
>  }
>  #else
>  static int
> -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
> +expected_nop_sequence(void *ip, struct ppc_inst op0, struct ppc_inst op1)
>  {
>  	/* look for patched "NOP" on ppc64 with -mprofile-kernel */
>  	if (!ppc_inst_equal(op0, ppc_inst(PPC_INST_NOP)))
> @@ -516,8 +517,8 @@ 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];
> -	unsigned int instr;
> +	struct ppc_inst op[2];
> +	struct ppc_inst instr;
>  	void *ip = (void *)rec->ip;
>  	unsigned long entry, ptr, tramp;
>  	struct module *mod = rec->arch.mod;
> @@ -528,7 +529,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_val(op[0]), ppc_inst_val(op[1]));


shouldn't this change be part of patch 6,

[PATCH v5 06/21] powerpc: Use an accessor for instructions


>  		return -EINVAL;
>  	}
>  
> @@ -582,7 +583,7 @@ static int
>  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>  {
>  	int err;
> -	unsigned int op;
> +	struct ppc_inst op;
>  	unsigned long ip = rec->ip;
>  
>  	/* read where this goes */
> @@ -602,7 +603,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> addr)
>  	}
>  
>  	/* create the branch to the trampoline */
> -	err = create_branch(&op, (unsigned int *)ip,
> +	err = create_branch(&op, (struct ppc_inst *)ip,
>  			    rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
>  	if (!err) {
>  		pr_err("REL24 out of range!\n");
> @@ -621,7 +622,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;
> +	struct ppc_inst op;
>  	void *ip = (void *)rec->ip;
>  	unsigned long tramp, entry, ptr;
>  
> @@ -669,7 +670,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;
> +	struct ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -708,7 +709,7 @@ static int
>  __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
>  					unsigned long addr)
>  {
> -	unsigned int op;
> +	struct ppc_inst op;
>  	unsigned long ip = rec->ip;
>  	unsigned long entry, ptr, tramp;
>  	struct module *mod = rec->arch.mod;
> @@ -756,7 +757,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((struct ppc_inst *)ip, addr, BRANCH_SET_LINK))
> {
>  			pr_err("REL24 out of range!\n");
>  			return -EINVAL;
>  		}
> @@ -784,12 +785,12 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> long old_addr,
>  	}
>  
>  	/* Ensure branch is within 24 bits */
> -	if (create_branch(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> +	if (create_branch(&op, (struct ppc_inst *)ip, tramp, BRANCH_SET_LINK))
> {
>  		pr_err("Branch out of range\n");
>  		return -EINVAL;
>  	}
>  
> -	if (patch_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> +	if (patch_branch((struct ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
>  		pr_err("REL24 out of range!\n");
>  		return -EINVAL;
>  	}
> @@ -802,7 +803,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;
> +	struct ppc_inst old, new;
>  
>  	/*
>  	 * If the calling address is more that 24 bits away,
> @@ -842,10 +843,10 @@ 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;
> +	struct ppc_inst old, new;
>  	int ret;
>  
> -	old = *(unsigned int *)&ftrace_call;
> +	old = *(struct ppc_inst *)&ftrace_call;
>  	new = ftrace_call_replace(ip, (unsigned long)func, 1);
>  	ret = ftrace_modify_code(ip, old, new);
>  
> @@ -853,7 +854,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 = *(struct ppc_inst *)&ftrace_regs_call;
>  		new = ftrace_call_replace(ip, (unsigned long)func, 1);
>  		ret = ftrace_modify_code(ip, old, new);
>  	}
> @@ -927,7 +928,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;
> +	struct ppc_inst old, new;
>  
>  	old = ftrace_call_replace(ip, stub, 0);
>  	new = ftrace_call_replace(ip, addr, 0);
> @@ -940,7 +941,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;
> +	struct ppc_inst old, new;
>  
>  	old = ftrace_call_replace(ip, addr, 0);
>  	new = ftrace_call_replace(ip, stub, 0);
> diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
> index c8d21e812d8c..bbf536e10902 100644
> --- a/arch/powerpc/kernel/vecemu.c
> +++ b/arch/powerpc/kernel/vecemu.c
> @@ -261,11 +261,12 @@ static unsigned int rfin(unsigned int x)
>  
>  int emulate_altivec(struct pt_regs *regs)
>  {
> -	unsigned int instr, i, word;
> +	struct ppc_inst instr;
> +	unsigned int i, word;
>  	unsigned int va, vb, vc, vd;
>  	vector128 *vrs;
>  
> -	if (get_user(instr, (unsigned int __user *) regs->nip))
> +	if (get_user(instr.val, (unsigned int __user *) regs->nip))


[...] reference to above for using helper.


>  		return -EFAULT;
>  
>  	word = ppc_inst_val(instr);
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index 33654c6334a9..91be4a0b51cb 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -19,12 +19,12 @@
>  #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(struct ppc_inst *exec_addr, struct ppc_inst
> instr,
> +			       struct ppc_inst *patch_addr)
>  {
>  	int err = 0;
>  
> -	__put_user_asm(instr, patch_addr, err, "stw");
> +	__put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw");
>  	if (err)
>  		return err;
>  
> @@ -34,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(struct ppc_inst *addr, struct ppc_inst instr)
>  {
>  	return __patch_instruction(addr, instr, addr);
>  }
> @@ -137,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(struct ppc_inst *addr, struct ppc_inst
> instr)
>  {
>  	int err;
> -	unsigned int *patch_addr = NULL;
> +	struct ppc_inst *patch_addr = NULL;
>  	unsigned long flags;
>  	unsigned long text_poke_addr;
>  	unsigned long kaddr = (unsigned long)addr;
> @@ -177,14 +177,14 @@ 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(struct ppc_inst *addr, struct ppc_inst
> instr)
>  {
>  	return raw_patch_instruction(addr, instr);
>  }
>  
>  #endif /* CONFIG_STRICT_KERNEL_RWX */
>  
> -int patch_instruction(unsigned int *addr, unsigned int instr)
> +int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr)
>  {
>  	/* Make sure we aren't patching a freed init section */
>  	if (init_mem_is_free && init_section_contains(addr, 4)) {
> @@ -195,9 +195,9 @@ 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(struct ppc_inst *addr, unsigned long target, int flags)
>  {
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  
>  	create_branch(&instr, addr, target, flags);
>  	return patch_instruction(addr, instr);
> @@ -229,7 +229,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(struct ppc_inst instr)
>  {
>  	unsigned int opcode = ppc_inst_opcode(instr);
>  
> @@ -247,13 +247,13 @@ bool is_conditional_branch(unsigned int instr)
>  }
>  NOKPROBE_SYMBOL(is_conditional_branch);
>  
> -int create_branch(unsigned int *instr,
> -		  const unsigned int *addr,
> +int create_branch(struct ppc_inst *instr,
> +		  const struct ppc_inst *addr,
>  		  unsigned long target, int flags)
>  {
>  	long offset;
>  
> -	*instr = 0;
> +	*instr = ppc_inst(0);
>  	offset = target;
>  	if (! (flags & BRANCH_ABSOLUTE))
>  		offset = offset - (unsigned long)addr;
> @@ -263,12 +263,12 @@ int create_branch(unsigned int *instr,
>  		return 1;
>  
>  	/* Mask out the flags and target, so they don't step on each other. */
> -	*instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
> +	*instr = ppc_inst(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC));
>  
>  	return 0;
>  }
>  
> -int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> +int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
>  		       unsigned long target, int flags)
>  {
>  	long offset;
> @@ -282,27 +282,27 @@ int create_cond_branch(unsigned int *instr, const
> unsigned int *addr,
>  		return 1;
>  
>  	/* Mask out the flags and target, so they don't step on each other. */
> -	*instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
> +	*instr = ppc_inst(0x40000000 | (flags & 0x3FF0003) | (offset &
> 0xFFFC));
>  
>  	return 0;
>  }
>  
> -static unsigned int branch_opcode(unsigned int instr)
> +static unsigned int branch_opcode(struct ppc_inst instr)
>  {
>  	return ppc_inst_opcode(instr) & 0x3F;
>  }
>  
> -static int instr_is_branch_iform(unsigned int instr)
> +static int instr_is_branch_iform(struct ppc_inst instr)
>  {
>  	return branch_opcode(instr) == 18;
>  }
>  
> -static int instr_is_branch_bform(unsigned int instr)
> +static int instr_is_branch_bform(struct ppc_inst instr)
>  {
>  	return branch_opcode(instr) == 16;
>  }
>  
> -int instr_is_relative_branch(unsigned int instr)
> +int instr_is_relative_branch(struct ppc_inst instr)
>  {
>  	if (ppc_inst_val(instr) & BRANCH_ABSOLUTE)
>  		return 0;
> @@ -310,12 +310,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(struct ppc_inst instr)
>  {
>  	return instr_is_relative_branch(instr) && (ppc_inst_val(instr) &
> BRANCH_SET_LINK);
>  }
>  
> -static unsigned long branch_iform_target(const unsigned int *instr)
> +static unsigned long branch_iform_target(const struct ppc_inst *instr)
>  {
>  	signed long imm;
>  
> @@ -331,7 +331,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 struct ppc_inst *instr)
>  {
>  	signed long imm;
>  
> @@ -347,7 +347,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 struct ppc_inst *instr)
>  {
>  	if (instr_is_branch_iform(*instr))
>  		return branch_iform_target(instr);
> @@ -357,7 +357,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 struct ppc_inst *instr, unsigned long
> addr)
>  {
>  	if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
>  		return branch_target(instr) == addr;
> @@ -365,7 +365,7 @@ int instr_is_branch_to_addr(const unsigned int *instr,
> unsigned long addr)
>  	return 0;
>  }
>  
> -int translate_branch(unsigned int *instr, const unsigned int *dest, const
> unsigned int *src)
> +int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
> const struct ppc_inst *src)
>  {
>  	unsigned long target;
>  
> @@ -408,7 +408,7 @@ static void __init test_trampoline(void)
>  static void __init test_branch_iform(void)
>  {
>  	int err;
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  	unsigned long addr;
>  
>  	addr = (unsigned long)&instr;
> @@ -483,12 +483,12 @@ static void __init test_branch_iform(void)
>  
>  static void __init test_create_function_call(void)
>  {
> -	unsigned int *iptr;
> +	struct ppc_inst *iptr;
>  	unsigned long dest;
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  
>  	/* Check we can create a function call */
> -	iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> +	iptr = (struct ppc_inst *)ppc_function_entry(test_trampoline);
>  	dest = ppc_function_entry(test_create_function_call);
>  	create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
>  	patch_instruction(iptr, instr);
> @@ -499,7 +499,8 @@ static void __init test_branch_bform(void)
>  {
>  	int err;
>  	unsigned long addr;
> -	unsigned int *iptr, instr, flags;
> +	struct ppc_inst *iptr, instr;
> +	unsigned int flags;
>  
>  	iptr = &instr;
>  	addr = (unsigned long)iptr;
> @@ -569,8 +570,8 @@ static void __init test_branch_bform(void)
>  static void __init test_translate_branch(void)
>  {
>  	unsigned long addr;
> -	unsigned int *p, *q;
> -	unsigned int instr;
> +	struct ppc_inst *p, *q;
> +	struct ppc_inst instr;
>  	void *buf;
>  
>  	buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> fixups.c
> index 6e7479b8887a..8c5d0db77013 100644
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -32,26 +32,26 @@ struct fixup_entry {
>  	long		alt_end_off;
>  };
>  
> -static unsigned int *calc_addr(struct fixup_entry *fcur, long offset)
> +static struct ppc_inst *calc_addr(struct fixup_entry *fcur, long offset)
>  {
>  	/*
>  	 * We store the offset to the code as a negative offset from
>  	 * the start of the alt_entry, to support the VDSO. This
>  	 * routine converts that back into an actual address.
>  	 */
> -	return (unsigned int *)((unsigned long)fcur + offset);
> +	return (struct ppc_inst *)((unsigned long)fcur + offset);
>  }
>  
> -static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
> -				 unsigned int *alt_start, unsigned int
> *alt_end)
> +static int patch_alt_instruction(struct ppc_inst *src, struct ppc_inst
> *dest,
> +				 struct ppc_inst *alt_start, struct ppc_inst
> *alt_end)
>  {
>  	int err;
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  
>  	instr = *src;
>  
>  	if (instr_is_relative_branch(*src)) {
> -		unsigned int *target = (unsigned int *)branch_target(src);
> +		struct ppc_inst *target = (struct ppc_inst
> *)branch_target(src);
>  
>  		/* Branch within the section doesn't need translating */
>  		if (target < alt_start || target > alt_end) {
> @@ -68,7 +68,7 @@ static int patch_alt_instruction(unsigned int *src,
> unsigned int *dest,
>  
>  static int patch_feature_section(unsigned long value, struct fixup_entry
> *fcur)
>  {
> -	unsigned int *start, *end, *alt_start, *alt_end, *src, *dest;
> +	struct ppc_inst *start, *end, *alt_start, *alt_end, *src, *dest;
>  
>  	start = calc_addr(fcur, fcur->start_off);
>  	end = calc_addr(fcur, fcur->end_off);
> @@ -147,15 +147,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, ppc_inst(instrs[0]));
> +		patch_instruction((struct ppc_inst *)dest,
> ppc_inst(instrs[0]));


we had already declared them as struct ppc_inst * 


>  
>  		if (types & STF_BARRIER_FALLBACK)
> -			patch_branch(dest + 1, (unsigned
> long)&stf_barrier_fallback,
> +			patch_branch((struct ppc_inst *)(dest + 1), (unsigned
> long)&stf_barrier_fallback,
>  				     BRANCH_SET_LINK);
>  		else
> -			patch_instruction(dest + 1, ppc_inst(instrs[1]));
> +			patch_instruction((struct ppc_inst *)(dest + 1),
> ppc_inst(instrs[1]));
>  
> -		patch_instruction(dest + 2, ppc_inst(instrs[2]));
> +		patch_instruction((struct ppc_inst *)(dest + 2),
> ppc_inst(instrs[2]));
>  	}
>  
>  	printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s
> barrier)\n", i,
> @@ -208,12 +208,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, 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]));
> +		patch_instruction((struct ppc_inst *)dest,
> ppc_inst(instrs[0]));
> +		patch_instruction((struct ppc_inst *)(dest + 1),
> ppc_inst(instrs[1]));
> +		patch_instruction((struct ppc_inst *)(dest + 2),
> ppc_inst(instrs[2]));
> +		patch_instruction((struct ppc_inst *)(dest + 3),
> ppc_inst(instrs[3]));
> +		patch_instruction((struct ppc_inst *)(dest + 4),
> ppc_inst(instrs[4]));
> +		patch_instruction((struct ppc_inst *)(dest + 5),
> ppc_inst(instrs[5]));
>  	}
>  	printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s
> barrier)\n", i,
>  		(types == STF_BARRIER_NONE)                  ? "no" :
> @@ -261,9 +261,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
>  
>  		pr_devel("patching dest %lx\n", (unsigned long)dest);
>  
> -		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((struct ppc_inst *)dest,
> ppc_inst(instrs[0]));
> +		patch_instruction((struct ppc_inst *)(dest + 1),
> ppc_inst(instrs[1]));
> +		patch_instruction((struct ppc_inst *)(dest + 2),
> ppc_inst(instrs[2]));
>  	}
>  
>  	printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
> @@ -296,7 +296,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, ppc_inst(instr));
> +		patch_instruction((struct ppc_inst *)dest, ppc_inst(instr));
>  	}
>  
>  	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
> @@ -339,8 +339,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, ppc_inst(instr[0]));
> -		patch_instruction(dest + 1, ppc_inst(instr[1]));
> +		patch_instruction((struct ppc_inst *)dest, ppc_inst(instr[0]));
> +		patch_instruction((struct ppc_inst *)(dest + 1),
> ppc_inst(instr[1]));
>  	}
>  
>  	printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
> @@ -373,7 +373,7 @@ void do_btb_flush_fixups(void)
>  void do_lwsync_fixups(unsigned long value, void *fixup_start, void
> *fixup_end)
>  {
>  	long *start, *end;
> -	unsigned int *dest;
> +	struct ppc_inst *dest;
>  
>  	if (!(value & CPU_FTR_LWSYNC))
>  		return ;
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 26e37176692e..52ddd3122dc8 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)
> +		  struct ppc_inst instr)


we need to take care of `instr` inside this function as well to adopt
the helpers to work with it.

-- Bala


>  {
>  	unsigned int opcode, ra, rb, rc, rd, spr, u;
>  	unsigned long int imm;
> @@ -3103,7 +3103,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, struct 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 16387a9bfda0..60b159b60545 100644
> --- a/arch/powerpc/lib/test_emulate_step.c
> +++ b/arch/powerpc/lib/test_emulate_step.c
> @@ -461,7 +461,7 @@ struct compute_test {
>  	struct {
>  		char *descr;
>  		unsigned long flags;
> -		unsigned int instr;
> +		struct ppc_inst instr;
>  		struct pt_regs regs;
>  	} subtests[MAX_SUBTESTS + 1];
>  };
> @@ -842,7 +842,7 @@ static struct compute_test compute_tests[] = {
>  };
>  
>  static int __init emulate_compute_instr(struct pt_regs *regs,
> -					unsigned int instr)
> +					struct ppc_inst instr)
>  {
>  	struct instruction_op op;
>  
> @@ -860,7 +860,7 @@ static int __init emulate_compute_instr(struct pt_regs
> *regs,
>  }
>  
>  static int __init execute_compute_instr(struct pt_regs *regs,
> -					unsigned int instr)
> +					struct ppc_inst instr)
>  {
>  	extern int exec_instr(struct pt_regs *regs);
>  	extern s32 patch__exec_instr;
> @@ -891,7 +891,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;
> +	struct 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/perf/core-book3s.c b/arch/powerpc/perf/core-
> book3s.c
> index 3086055bf681..2d2580a4bfb5 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -421,14 +421,14 @@ static __u64 power_pmu_bhrb_to(u64 addr)
>  		if (probe_kernel_read(&instr, (void *)addr, sizeof(instr)))
>  			return 0;
>  
> -		return branch_target(&instr);
> +		return branch_target((struct ppc_inst *)&instr);
>  	}
>  
>  	/* Userspace: need copy instruction here then translate it */
>  	if (probe_user_read(&instr, (unsigned int __user *)addr,
> sizeof(instr)))
>  		return 0;
>  
> -	target = branch_target(&instr);
> +	target = branch_target((struct ppc_inst *)&instr);
>  	if ((!target) || (instr & BRANCH_ABSOLUTE))
>  		return target;
>  
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index f6c87d3d53ea..e3d8e1b8ce01 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -99,7 +99,7 @@ static long *xmon_fault_jmp[NR_CPUS];
>  /* Breakpoint stuff */
>  struct bpt {
>  	unsigned long	address;
> -	unsigned int	*instr;
> +	struct ppc_inst	*instr;
>  	atomic_t	ref_count;
>  	int		enabled;
>  	unsigned long	pad;
> @@ -117,7 +117,7 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
>  
>  #define BP_NUM(bp)	((bp) - bpts + 1)
>  
> -#define BPT_SIZE	(sizeof(unsigned int) * 2)
> +#define BPT_SIZE	(sizeof(struct ppc_inst) * 2)
>  #define BPT_WORDS	(BPT_SIZE / sizeof(unsigned int))
>  extern unsigned int bpt_table[NBPTS * BPT_WORDS];
>  
> @@ -879,8 +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;
> -			bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> -			patch_instruction(bp->instr + 1, bpinstr);
> +			bp->instr = (void *)(bpt_table + ((bp - bpts) *
> BPT_WORDS));
> +			patch_instruction(bp->instr + 1, ppc_inst(bpinstr));
>  			return bp;
>  		}
>  	}
> @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
>  static void insert_bpts(void)
>  {
>  	int i;
> -	unsigned int instr;
> +	struct ppc_inst instr;
>  	struct bpt *bp;
>  
>  	bp = bpts;
> @@ -914,8 +914,8 @@ static void insert_bpts(void)
>  		patch_instruction(bp->instr, instr);
>  		if (bp->enabled & BP_CIABR)
>  			continue;
> -		if (patch_instruction((unsigned int *)bp->address,
> -							bpinstr) != 0) {
> +		if (patch_instruction((struct ppc_inst *)bp->address,
> +							ppc_inst(bpinstr)) !=
> 0) {
>  			printf("Couldn't write instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
>  			bp->enabled &= ~BP_TRAP;
> @@ -943,7 +943,7 @@ static void remove_bpts(void)
>  {
>  	int i;
>  	struct bpt *bp;
> -	unsigned instr;
> +	struct 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
>  		    && ppc_inst_equal(instr, ppc_inst(bpinstr))
>  		    && patch_instruction(
> -			(unsigned int *)bp->address, bp->instr[0]) != 0)
> +			(struct 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;
> +	struct 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;
> +	struct ppc_inst instr;
>  
>  	addr &= ~3;
>  	if (!is_kernel_addr(addr)) {
> @@ -2846,7 +2846,7 @@ generic_inst_dump(unsigned long adr, long count, int
> praddr,
>  {
>  	int nr, dotted;
>  	unsigned long first_adr;
> -	unsigned int inst, last_inst = ppc_inst(0);
> +	struct ppc_inst inst, last_inst = ppc_inst(0);
>  	unsigned char val[4];
>  
>  	dotted = 0;


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

* Re: [PATCH v5 10/21] powerpc: Use a function for reading instructions
  2020-04-06  8:09 ` [PATCH v5 10/21] powerpc: Use a function for reading instructions Jordan Niethe
@ 2020-04-07 10:42   ` Balamuruhan S
  0 siblings, 0 replies; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07 10:42 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> 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
> v5: - Rename read_inst() -> probe_kernel_read_inst()
>     - No longer modify uprobe probe type in this patch
> ---
>  arch/powerpc/include/asm/inst.h    |  5 +++++
>  arch/powerpc/kernel/kprobes.c      | 11 ++++------
>  arch/powerpc/kernel/mce_power.c    |  2 +-
>  arch/powerpc/kernel/optprobes.c    |  4 ++--
>  arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++-----------
>  arch/powerpc/lib/code-patching.c   | 23 ++++++++++-----------
>  arch/powerpc/lib/feature-fixups.c  |  2 +-
>  arch/powerpc/xmon/xmon.c           |  6 +++---
>  8 files changed, 48 insertions(+), 38 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> index a71decf5f871..369b35ce964c 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -27,6 +27,11 @@ static inline struct ppc_inst ppc_inst_swab(struct
> ppc_inst x)
>  	return ppc_inst(swab32(ppc_inst_val(x)));
>  }
>  
> +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> +{
> +	return *ptr;
> +}
> +
>  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
>  {
>  	return !memcmp(&x, &y, sizeof(struct ppc_inst));
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 9ed996cb0589..ff53e5ef7e40 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name,
> unsigned int offset)
>  int arch_prepare_kprobe(struct kprobe *p)
>  {
>  	int ret = 0;
> -	struct ppc_inst insn = *(struct ppc_inst *)p->addr;
> +	struct ppc_inst insn = ppc_inst_read((struct ppc_inst *)p->addr);
>  
>  	if ((unsigned long)p->addr & 0x03) {
>  		printk("Attempt to register kprobe at an unaligned address\n");
> @@ -125,11 +125,8 @@ int arch_prepare_kprobe(struct kprobe *p)
>  	}
>  
>  	if (!ret) {
> -		memcpy(p->ainsn.insn, p->addr,
> -				MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
> -		p->opcode = *p->addr;
> -		flush_icache_range((unsigned long)p->ainsn.insn,
> -			(unsigned long)p->ainsn.insn +
> sizeof(kprobe_opcode_t));
> +		patch_instruction((struct ppc_inst *)p->ainsn.insn, insn);
> +		p->opcode = ppc_inst_val(insn);


This is a different change from this commit

-- Bala
>  	}
>  
>  	p->ainsn.boostable = 0;
> @@ -217,7 +214,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
>  static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
>  {
>  	int ret;
> -	struct ppc_inst insn = *(struct ppc_inst *)p->ainsn.insn;
> +	struct ppc_inst insn = ppc_inst_read((struct 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 7118b46a6543..859b602fa270 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 = *(struct ppc_inst *)(instr_addr);
> +		instr = ppc_inst_read((struct 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 b61bbcee84f4..684640b8fa2e 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -100,8 +100,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(*(struct ppc_inst *)p->ainsn.insn) &&
> -			analyse_instr(&op, &regs, *(struct ppc_inst *)p-
> >ainsn.insn) == 1) {
> +	if (!is_conditional_branch(ppc_inst_read((struct ppc_inst *)p-
> >ainsn.insn)) &&
> +			analyse_instr(&op, &regs, ppc_inst_read((struct
> ppc_inst *)p->ainsn.insn)) == 1) {
>  		emulate_update_regs(&regs, &op);
>  		nip = regs.nip;
>  	}
> diff --git a/arch/powerpc/kernel/trace/ftrace.c
> b/arch/powerpc/kernel/trace/ftrace.c
> index 442c62fb68ff..e78742613b36 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
> +probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> +{
> +	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> +}
> +
>  static struct ppc_inst
>  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
>  {
> @@ -68,7 +74,7 @@ ftrace_modify_code(unsigned long ip, struct ppc_inst old,
> struct ppc_inst new)
>  	 */
>  
>  	/* read the text we want to modify */
> -	if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
> +	if (probe_kernel_read_inst(&replaced, (void *)ip))
>  		return -EFAULT;
>  
>  	/* Make sure it is what we expect it to be */
> @@ -130,7 +136,7 @@ __ftrace_make_nop(struct module *mod,
>  	struct ppc_inst op, pop;
>  
>  	/* read where this goes */
> -	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> +	if (probe_kernel_read_inst(&op, (void *)ip)) {
>  		pr_err("Fetching opcode failed.\n");
>  		return -EFAULT;
>  	}
> @@ -164,7 +170,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 (probe_kernel_read_inst(&op, (void *)(ip - 4))) {
>  		pr_err("Fetching instruction at %lx failed.\n", ip - 4);
>  		return -EFAULT;
>  	}
> @@ -196,7 +202,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 (probe_kernel_read_inst(&op, (void *)(ip+4))) {
>  		pr_err("Fetching op failed.\n");
>  		return -EFAULT;
>  	}
> @@ -348,7 +354,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 (probe_kernel_read_inst(&op, (void *)tramp)) {
>  		pr_debug("Fetching opcode failed.\n");
>  		return -1;
>  	}
> @@ -398,7 +404,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> *rec, unsigned long addr)
>  	struct ppc_inst op;
>  
>  	/* Read where this goes */
> -	if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> +	if (probe_kernel_read_inst(&op, (void *)ip)) {
>  		pr_err("Fetching opcode failed.\n");
>  		return -EFAULT;
>  	}
> @@ -524,7 +530,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 (probe_kernel_read_inst(op, ip))
> +		return -EFAULT;
> +
> +	if (probe_kernel_read_inst(op + 1, ip + 4))
>  		return -EFAULT;
>  
>  	if (!expected_nop_sequence(ip, op[0], op[1])) {
> @@ -587,7 +596,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 (probe_kernel_read_inst(&op, (void *)ip))
>  		return -EFAULT;
>  
>  	/* It should be pointing to a nop */
> @@ -643,7 +652,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 (probe_kernel_read_inst(&op, ip)) {
>  		pr_err("Unable to read ftrace location %p\n", ip);
>  		return -EFAULT;
>  	}
> @@ -721,7 +730,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 (probe_kernel_read_inst(&op, (void *)ip)) {
>  		pr_err("Fetching opcode failed.\n");
>  		return -EFAULT;
>  	}
> @@ -846,7 +855,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
>  	struct ppc_inst old, new;
>  	int ret;
>  
> -	old = *(struct ppc_inst *)&ftrace_call;
> +	old = ppc_inst_read((struct ppc_inst *)&ftrace_call);
>  	new = ftrace_call_replace(ip, (unsigned long)func, 1);
>  	ret = ftrace_modify_code(ip, old, new);
>  
> @@ -854,7 +863,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 = *(struct ppc_inst *)&ftrace_regs_call;
> +		old = ppc_inst_read((struct 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/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index 91be4a0b51cb..ba08f3815d00 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -349,9 +349,9 @@ static unsigned long branch_bform_target(const struct
> ppc_inst *instr)
>  
>  unsigned long branch_target(const struct 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;
> @@ -359,7 +359,7 @@ unsigned long branch_target(const struct ppc_inst *instr)
>  
>  int instr_is_branch_to_addr(const struct 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,13 +368,12 @@ int instr_is_branch_to_addr(const struct ppc_inst
> *instr, unsigned long addr)
>  int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
> const struct ppc_inst *src)
>  {
>  	unsigned long target;
> -
>  	target = branch_target(src);
>  
> -	if (instr_is_branch_iform(*src))
> -		return create_branch(instr, dest, target, ppc_inst_val(*src));
> -	else if (instr_is_branch_bform(*src))
> -		return create_cond_branch(instr, dest, target,
> ppc_inst_val(*src));
> +	if (instr_is_branch_iform(ppc_inst_read(src)))
> +		return create_branch(instr, dest, target,
> ppc_inst_val(ppc_inst_read(src)));
> +	else if (instr_is_branch_bform(ppc_inst_read(src)))
> +		return create_cond_branch(instr, dest, target,
> ppc_inst_val(ppc_inst_read(src)));
>  
>  	return 1;
>  }
> @@ -598,7 +597,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
> -	check(ppc_inst_equal(*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;
> @@ -609,7 +608,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
> -	check(ppc_inst_equal(*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;
> @@ -655,7 +654,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
> -	check(ppc_inst_equal(*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;
> @@ -667,7 +666,7 @@ static void __init test_translate_branch(void)
>  	patch_instruction(q, instr);
>  	check(instr_is_branch_to_addr(p, addr));
>  	check(instr_is_branch_to_addr(q, addr));
> -	check(ppc_inst_equal(*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 8c5d0db77013..f00dd13b1c3c 100644
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -48,7 +48,7 @@ static int patch_alt_instruction(struct ppc_inst *src,
> struct ppc_inst *dest,
>  	int err;
>  	struct ppc_inst instr;
>  
> -	instr = *src;
> +	instr = ppc_inst_read(src);
>  
>  	if (instr_is_relative_branch(*src)) {
>  		struct ppc_inst *target = (struct ppc_inst
> *)branch_target(src);
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index e3d8e1b8ce01..5e3949322a6c 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -705,13 +705,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");
>  			}
>  		}
>  	}
> @@ -952,7 +952,7 @@ static void remove_bpts(void)
>  		if (mread(bp->address, &instr, 4) == 4
>  		    && ppc_inst_equal(instr, ppc_inst(bpinstr))
>  		    && patch_instruction(
> -			(struct ppc_inst *)bp->address, bp->instr[0]) != 0)
> +			(struct ppc_inst *)bp->address, ppc_inst_read(bp-
> >instr)) != 0)
>  			printf("Couldn't remove breakpoint at %lx\n",
>  			       bp->address);
>  	}


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

* Re: [PATCH v5 11/21] powerpc: Define and use __get_user_instr{, inatomic}()
  2020-04-06  8:09 ` [PATCH v5 11/21] powerpc: Define and use __get_user_instr{, inatomic}() Jordan Niethe
@ 2020-04-07 10:48   ` Balamuruhan S
  2020-04-08  2:13     ` Jordan Niethe
  0 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07 10:48 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> Define specific __get_user_instr() and __get_user_instr_inatomic()
> macros for reading instructions from user space.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>  arch/powerpc/include/asm/uaccess.h  | 5 +++++
>  arch/powerpc/kernel/align.c         | 2 +-
>  arch/powerpc/kernel/hw_breakpoint.c | 2 +-
>  arch/powerpc/kernel/vecemu.c        | 2 +-
>  4 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/uaccess.h
> b/arch/powerpc/include/asm/uaccess.h
> index 2f500debae21..c0a35e4586a5 100644
> --- a/arch/powerpc/include/asm/uaccess.h
> +++ b/arch/powerpc/include/asm/uaccess.h
> @@ -105,6 +105,11 @@ 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)))
>  
> +#define __get_user_instr(x, ptr) \
> +	__get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> +
> +#define __get_user_instr_inatomic(x, ptr) \
> +	__get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))


should we use ppc_inst_val() ?

-- Bala


>  extern long __put_user_bad(void);
>  
>  /*
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index 66a6d1de7799..65cdfd41e3a1 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -304,7 +304,7 @@ int fix_alignment(struct pt_regs *regs)
>  	 */
>  	CHECK_FULL_REGS(regs);
>  
> -	if (unlikely(__get_user(instr.val, (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... */
> diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> b/arch/powerpc/kernel/hw_breakpoint.c
> index 542f65ccf68b..cebab14e2788 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.val, (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/vecemu.c b/arch/powerpc/kernel/vecemu.c
> index bbf536e10902..c82ede46d71b 100644
> --- a/arch/powerpc/kernel/vecemu.c
> +++ b/arch/powerpc/kernel/vecemu.c
> @@ -266,7 +266,7 @@ int emulate_altivec(struct pt_regs *regs)
>  	unsigned int va, vb, vc, vd;
>  	vector128 *vrs;
>  
> -	if (get_user(instr.val, (unsigned int __user *) regs->nip))
> +	if (__get_user_instr(instr, (void __user *) regs->nip))
>  		return -EFAULT;
>  
>  	word = ppc_inst_val(instr);


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

* Re: [PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length
  2020-04-06  8:09 ` [PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length Jordan Niethe
@ 2020-04-07 11:14   ` Balamuruhan S
  2020-04-08  2:14     ` Jordan Niethe
  0 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07 11:14 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> Currently all instructions have the same length, but in preparation for
> prefixed instructions introduce a function for returning instruction
> length.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>  arch/powerpc/include/asm/inst.h | 5 +++++
>  arch/powerpc/kernel/kprobes.c   | 6 ++++--
>  arch/powerpc/kernel/uprobes.c   | 2 +-
>  3 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> index 369b35ce964c..70b37a35a91a 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -17,6 +17,11 @@ static inline u32 ppc_inst_val(struct ppc_inst x)
>  	return x.val;
>  }
>  
> +static inline bool ppc_inst_len(struct ppc_inst x)


return type shouldn't be a bool, `size_t` instead.

-- Bala

> +{
> +	return sizeof(struct ppc_inst);
> +}
> +
>  static inline int ppc_inst_opcode(struct ppc_inst x)
>  {
>  	return x.val >> 26;
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index ff53e5ef7e40..8d17cfdcdc54 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -474,14 +474,16 @@ NOKPROBE_SYMBOL(trampoline_probe_handler);
>   */
>  int kprobe_post_handler(struct pt_regs *regs)
>  {
> +	int len;
>  	struct kprobe *cur = kprobe_running();
>  	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
>  
>  	if (!cur || user_mode(regs))
>  		return 0;
>  
> +	len = ppc_inst_len(ppc_inst_read((struct ppc_inst *)cur->ainsn.insn));
>  	/* make sure we got here for instruction we have a kprobe on */
> -	if (((unsigned long)cur->ainsn.insn + 4) != regs->nip)
> +	if (((unsigned long)cur->ainsn.insn + len) != regs->nip)
>  		return 0;
>  
>  	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
> @@ -490,7 +492,7 @@ int kprobe_post_handler(struct pt_regs *regs)
>  	}
>  
>  	/* Adjust nip to after the single-stepped instruction */
> -	regs->nip = (unsigned long)cur->addr + 4;
> +	regs->nip = (unsigned long)cur->addr + len;
>  	regs->msr |= kcb->kprobe_saved_msr;
>  
>  	/*Restore back the original saved kprobes variables and continue. */
> diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
> index 31c870287f2b..8e63afa012ba 100644
> --- a/arch/powerpc/kernel/uprobes.c
> +++ b/arch/powerpc/kernel/uprobes.c
> @@ -112,7 +112,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe,
> struct pt_regs *regs)
>  	 * support doesn't exist and have to fix-up the next instruction
>  	 * to be executed.
>  	 */
> -	regs->nip = utask->vaddr + MAX_UINSN_BYTES;
> +	regs->nip = utask->vaddr + ppc_inst_len(auprobe->insn);
>  
>  	user_disable_single_step(current);
>  	return 0;


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

* Re: [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions
  2020-04-06  8:09 ` [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions Jordan Niethe
@ 2020-04-07 11:30   ` Balamuruhan S
  2020-04-08  2:18     ` Jordan Niethe
  0 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-07 11:30 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> Currently in xmon, mread() is used for reading instructions. In
> preparation for prefixed instructions, create and use a new function,
> mread_instr(), especially for reading instructions.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
> v5: New to series, seperated from "Add prefixed instructions to
> instruction data type"
> ---
>  arch/powerpc/xmon/xmon.c | 24 ++++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 5e3949322a6c..6f4cf01a58c1 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -125,6 +125,7 @@ extern unsigned int bpt_table[NBPTS * BPT_WORDS];
>  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, struct ppc_inst *);
>  static int handle_fault(struct pt_regs *);
>  static void byterev(unsigned char *, int);
>  static void memex(void);
> @@ -899,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)) {


Are these checks made based on whether `ppc_inst_len()` returns bool from
mread_instr() ?

-- Bala


>  			printf("Couldn't read instruction at %lx, "
>  			       "disabling breakpoint there\n", bp->address);
>  			bp->enabled = 0;
> @@ -949,7 +950,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(
>  			(struct ppc_inst *)bp->address, ppc_inst_read(bp-
> >instr)) != 0)
> @@ -1165,7 +1166,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",
> @@ -1332,7 +1333,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;
>  	}
> @@ -2125,6 +2126,21 @@ mwrite(unsigned long adrs, void *buf, int size)
>  	return n;
>  }
>  
> +static int
> +mread_instr(unsigned long adrs, struct ppc_inst *instr)
> +{
> +	if (setjmp(bus_error_jmp) == 0) {
> +		catch_memory_errors = 1;
> +		sync();
> +		*instr = ppc_inst_read((struct ppc_inst *)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] 71+ messages in thread

* Re: [PATCH v5 09/21] powerpc: Use a datatype for instructions
  2020-04-07 10:30   ` Balamuruhan S
@ 2020-04-08  2:11     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-08  2:11 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Tue, Apr 7, 2020 at 8:30 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, 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>
> > ---
> > v4: New to series
> > v5: Add to epapr_paravirt.c, kgdb.c
> > ---
> >  arch/powerpc/include/asm/code-patching.h | 32 ++++-----
> >  arch/powerpc/include/asm/inst.h          | 20 +++---
> >  arch/powerpc/include/asm/sstep.h         |  5 +-
> >  arch/powerpc/include/asm/uprobes.h       |  5 +-
> >  arch/powerpc/kernel/align.c              |  4 +-
> >  arch/powerpc/kernel/epapr_paravirt.c     |  4 +-
> >  arch/powerpc/kernel/hw_breakpoint.c      |  4 +-
> >  arch/powerpc/kernel/jump_label.c         |  2 +-
> >  arch/powerpc/kernel/kgdb.c               |  4 +-
> >  arch/powerpc/kernel/kprobes.c            |  8 +--
> >  arch/powerpc/kernel/mce_power.c          |  5 +-
> >  arch/powerpc/kernel/optprobes.c          | 40 ++++++------
> >  arch/powerpc/kernel/setup_32.c           |  2 +-
> >  arch/powerpc/kernel/trace/ftrace.c       | 83 ++++++++++++------------
> >  arch/powerpc/kernel/vecemu.c             |  5 +-
> >  arch/powerpc/lib/code-patching.c         | 69 ++++++++++----------
> >  arch/powerpc/lib/feature-fixups.c        | 48 +++++++-------
> >  arch/powerpc/lib/sstep.c                 |  4 +-
> >  arch/powerpc/lib/test_emulate_step.c     |  9 +--
> >  arch/powerpc/perf/core-book3s.c          |  4 +-
> >  arch/powerpc/xmon/xmon.c                 | 24 +++----
> >  21 files changed, 196 insertions(+), 185 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/code-patching.h
> > b/arch/powerpc/include/asm/code-patching.h
> > index 48e021957ee5..eacc9102c251 100644
> > --- a/arch/powerpc/include/asm/code-patching.h
> > +++ b/arch/powerpc/include/asm/code-patching.h
> > @@ -23,33 +23,33 @@
> >  #define BRANCH_ABSOLUTE      0x2
> >
> >  bool is_offset_in_branch_range(long offset);
> > -int create_branch(unsigned int *instr, const unsigned int *addr,
> > +int create_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
> >                 unsigned long target, int flags);
> > -int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> > +int create_cond_branch(struct ppc_inst *instr, const struct 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(struct ppc_inst *addr, unsigned long target, int flags);
> > +int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
> > +int raw_patch_instruction(struct ppc_inst *addr, struct 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, struct ppc_inst instr)
> >  {
> > -     return patch_instruction((unsigned int *)patch_site_addr(site), instr);
> > +     return patch_instruction((struct 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((struct ppc_inst *)patch_site_addr(site), target,
> > flags);
> >  }
> >
> >  static inline int modify_instruction(unsigned int *addr, unsigned int clr,
> >                                    unsigned int set)
> >  {
> > -     return patch_instruction(addr, ppc_inst((*addr & ~clr) | set));
> > +     return patch_instruction((struct ppc_inst *)addr, ppc_inst((*addr &
> > ~clr) | set));
> >  }
> >
> >  static inline int modify_instruction_site(s32 *site, unsigned int clr,
> > unsigned int set)
> > @@ -57,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);
> > -int translate_branch(unsigned int *instr, const unsigned int *dest,
> > -                  const unsigned int *src);
> > -extern bool is_conditional_branch(unsigned int instr);
> > +int instr_is_relative_branch(struct ppc_inst instr);
> > +int instr_is_relative_link_branch(struct ppc_inst instr);
> > +int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long
> > addr);
> > +unsigned long branch_target(const struct ppc_inst *instr);
> > +int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
> > +                  const struct ppc_inst *src);
> > +extern bool is_conditional_branch(struct 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
> > index 54ee46b0a7c9..a71decf5f871 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -6,26 +6,30 @@
> >   * Instruction data type for POWER
> >   */
> >
> > -#define ppc_inst(x) (x)
> > +struct ppc_inst {
> > +        u32 val;
> > +} __packed;
> >
> > -static inline u32 ppc_inst_val(u32 x)
> > +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > +
> > +static inline u32 ppc_inst_val(struct ppc_inst x)
> >  {
> > -     return x;
> > +     return x.val;
> >  }
> >
> > -static inline int ppc_inst_opcode(u32 x)
> > +static inline int ppc_inst_opcode(struct ppc_inst x)
> >  {
> > -     return x >> 26;
> > +     return x.val >> 26;
> >  }
> >
> > -static inline u32 ppc_inst_swab(u32 x)
> > +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> >  {
> >       return ppc_inst(swab32(ppc_inst_val(x)));
> >  }
> >
> > -static inline bool ppc_inst_equal(u32 x, u32 y)
> > +static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
> >  {
> > -     return x == y;
> > +     return !memcmp(&x, &y, sizeof(struct ppc_inst));
> >  }
> >
> >  #endif /* _ASM_INST_H */
> > diff --git a/arch/powerpc/include/asm/sstep.h
> > b/arch/powerpc/include/asm/sstep.h
> > index 26d729562fe2..c3ce903ac488 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);
> > +                      struct 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, struct ppc_inst instr);
> >
> >  /*
> >   * Emulate a load or store instruction by reading/writing the
> > diff --git a/arch/powerpc/include/asm/uprobes.h
> > b/arch/powerpc/include/asm/uprobes.h
> > index 2bbdf27d09b5..7e3b329ba2d3 100644
> > --- a/arch/powerpc/include/asm/uprobes.h
> > +++ b/arch/powerpc/include/asm/uprobes.h
> > @@ -11,6 +11,7 @@
> >
> >  #include <linux/notifier.h>
> >  #include <asm/probes.h>
> > +#include <asm/inst.h>
> >
> >  typedef ppc_opcode_t uprobe_opcode_t;
> >
> > @@ -23,8 +24,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
> >
> >  struct arch_uprobe {
> >       union {
> > -             u32     insn;
> > -             u32     ixol;
> > +             struct ppc_inst insn;
> > +             struct ppc_inst ixol;
> >       };
> >  };
> >
> > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > index 46870cf6a6dc..66a6d1de7799 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -294,7 +294,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int
> > reg,
> >
> >  int fix_alignment(struct pt_regs *regs)
> >  {
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >       struct instruction_op op;
> >       int r, type;
> >
> > @@ -304,7 +304,7 @@ 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.val, (unsigned int __user *)regs->nip)))
>
>
> don't we have to use the helper `ppc_inst_val()` here to retrieve instr.val ?
__get_user() is loading into instr.val, so using ppc_inst_val() would not work.
>
> I see couple of other places we directly retrieve as instr.val.
> if we need to change it, then all of them should go to patch 6,
Those other places also are for the __get_user() macros I think.
> [PATCH v5 06/21] powerpc: Use an accessor for instructions
>
>
> >               return -EFAULT;
> >       if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
> >               /* We don't handle PPC little-endian any more... */
> > diff --git a/arch/powerpc/kernel/epapr_paravirt.c
> > b/arch/powerpc/kernel/epapr_paravirt.c
> > index c53e863fb484..c42aa3926632 100644
> > --- a/arch/powerpc/kernel/epapr_paravirt.c
> > +++ b/arch/powerpc/kernel/epapr_paravirt.c
> > @@ -38,9 +38,9 @@ static int __init early_init_dt_scan_epapr(unsigned long
> > node,
> >
> >       for (i = 0; i < (len / 4); i++) {
> >               u32 inst = be32_to_cpu(insts[i]);
> > -             patch_instruction(epapr_hypercall_start + i, ppc_inst(inst));
> > +             patch_instruction((struct ppc_inst *)(epapr_hypercall_start +
> > i), ppc_inst(inst));
> >  #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
> > -             patch_instruction(epapr_ev_idle_start + i, ppc_inst(inst));
> > +             patch_instruction((struct ppc_inst *)(epapr_ev_idle_start + i),
> > ppc_inst(inst));
> >  #endif
> >       }
> >
> > diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> > b/arch/powerpc/kernel/hw_breakpoint.c
> > index 79f51f182a83..542f65ccf68b 100644
> > --- a/arch/powerpc/kernel/hw_breakpoint.c
> > +++ b/arch/powerpc/kernel/hw_breakpoint.c
> > @@ -244,12 +244,12 @@ 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 = ppc_inst(0);
> > +     struct ppc_inst instr = ppc_inst(0);
> >       int ret, type, size;
> >       struct instruction_op op;
> >       unsigned long addr = info->address;
> >
> > -     if (__get_user_inatomic(instr, (unsigned int *)regs->nip))
> > +     if (__get_user_inatomic(instr.val, (unsigned int *)regs->nip))
>
>
> [...] reference to above
>
>
> >               goto fail;
> >
> >       ret = analyse_instr(&op, regs, instr);
> > diff --git a/arch/powerpc/kernel/jump_label.c
> > b/arch/powerpc/kernel/jump_label.c
> > index daa4afce7ec8..144858027fa3 100644
> > --- a/arch/powerpc/kernel/jump_label.c
> > +++ b/arch/powerpc/kernel/jump_label.c
> > @@ -11,7 +11,7 @@
> >  void arch_jump_label_transform(struct jump_entry *entry,
> >                              enum jump_label_type type)
> >  {
> > -     u32 *addr = (u32 *)(unsigned long)entry->code;
> > +     struct ppc_inst *addr = (struct ppc_inst *)(unsigned long)entry->code;
> >
> >       if (type == JUMP_LABEL_JMP)
> >               patch_branch(addr, entry->target, 0);
> > diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
> > index a6b38a19133f..652b2852bea3 100644
> > --- a/arch/powerpc/kernel/kgdb.c
> > +++ b/arch/powerpc/kernel/kgdb.c
> > @@ -419,7 +419,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
> >  {
> >       int err;
> >       unsigned int instr;
> > -     unsigned int *addr = (unsigned int *)bpt->bpt_addr;
> > +     struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
> >
> >       err = probe_kernel_address(addr, instr);
> >       if (err)
> > @@ -438,7 +438,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
> >  {
> >       int err;
> >       unsigned int instr = *(unsigned int *)bpt->saved_instr;
> > -     unsigned int *addr = (unsigned int *)bpt->bpt_addr;
> > +     struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
> >
> >       err = patch_instruction(addr, ppc_inst(instr));
> >       if (err)
> > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> > index 8420b1944164..9ed996cb0589 100644
> > --- a/arch/powerpc/kernel/kprobes.c
> > +++ b/arch/powerpc/kernel/kprobes.c
> > @@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name,
> > unsigned int offset)
> >  int arch_prepare_kprobe(struct kprobe *p)
> >  {
> >       int ret = 0;
> > -     kprobe_opcode_t insn = *p->addr;
> > +     struct ppc_inst insn = *(struct ppc_inst *)p->addr;
> >
> >       if ((unsigned long)p->addr & 0x03) {
> >               printk("Attempt to register kprobe at an unaligned address\n");
> > @@ -139,13 +139,13 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
> >
> >  void arch_arm_kprobe(struct kprobe *p)
> >  {
> > -     patch_instruction(p->addr, ppc_inst(BREAKPOINT_INSTRUCTION));
> > +     patch_instruction((struct ppc_inst *)p->addr,
> > ppc_inst(BREAKPOINT_INSTRUCTION));
> >  }
> >  NOKPROBE_SYMBOL(arch_arm_kprobe);
> >
> >  void arch_disarm_kprobe(struct kprobe *p)
> >  {
> > -     patch_instruction(p->addr, ppc_inst(p->opcode));
> > +     patch_instruction((struct ppc_inst *)p->addr, ppc_inst(p->opcode));
> >  }
> >  NOKPROBE_SYMBOL(arch_disarm_kprobe);
> >
> > @@ -217,7 +217,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;
> > +     struct ppc_inst insn = *(struct 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 1cbf7f1a4e3d..7118b46a6543 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;
> > +     struct 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 = *(struct 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 3b33ebf18859..b61bbcee84f4 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -100,8 +100,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(*(struct ppc_inst *)p->ainsn.insn) &&
> > +                     analyse_instr(&op, &regs, *(struct ppc_inst *)p-
> > >ainsn.insn) == 1) {
> >               emulate_update_regs(&regs, &op);
> >               nip = regs.nip;
> >       }
> > @@ -148,12 +148,12 @@ 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(PPC_INST_ADDIS | ___PPC_RT(4) |
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> > ___PPC_RT(4) |
> >                         ((val >> 16) & 0xffff)));
> >       addr++;
> >
> >       /* ori r4,r4,(insn)@l */
> > -     patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(4) |
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > ___PPC_RA(4) |
> >                         ___PPC_RS(4) | (val & 0xffff)));
> >  }
> >
> > @@ -164,34 +164,34 @@ 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(PPC_INST_ADDIS | ___PPC_RT(3) |
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> > ___PPC_RT(3) |
> >                         ((val >> 48) & 0xffff)));
> >       addr++;
> >
> >       /* ori r3,r3,(op)@higher */
> > -     patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(3) |
> > +     patch_instruction((struct ppc_inst *)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(PPC_INST_RLDICR | ___PPC_RA(3) |
> > +     patch_instruction((struct ppc_inst *)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(PPC_INST_ORIS | ___PPC_RA(3) |
> > +     patch_instruction((struct ppc_inst *)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(PPC_INST_ORI | ___PPC_RA(3) |
> > +     patch_instruction((struct ppc_inst *)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)
> >  {
> > -     kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step;
> > -     kprobe_opcode_t *op_callback_addr, *emulate_step_addr;
> > +     struct 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;
> > @@ -231,7 +231,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,
> > ppc_inst(*(optprobe_template_entry + i)));
> > +             rc = patch_instruction((struct ppc_inst *)(buff + i),
> > ppc_inst(*(optprobe_template_entry + i)));
> >               if (rc < 0)
> >                       goto error;
> >       }
> > @@ -253,20 +253,20 @@ int arch_prepare_optimized_kprobe(struct
> > optimized_kprobe *op, struct kprobe *p)
> >       }
> >
> >       rc = create_branch(&branch_op_callback,
> > -                        (unsigned int *)buff + TMPL_CALL_HDLR_IDX,
> > +                        (struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX),
> >                          (unsigned long)op_callback_addr,
> >                          BRANCH_SET_LINK);
> >
> >       rc |= create_branch(&branch_emulate_step,
> > -                         (unsigned int *)buff + TMPL_EMULATE_IDX,
> > +                         (struct ppc_inst *)(buff + TMPL_EMULATE_IDX),
> >                           (unsigned long)emulate_step_addr,
> >                           BRANCH_SET_LINK);
> >
> >       if (rc)
> >               goto error;
> >
> > -     patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
> > -     patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step);
> > +     patch_instruction((struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX),
> > branch_op_callback);
> > +     patch_instruction((struct ppc_inst *)(buff + TMPL_EMULATE_IDX),
> > branch_emulate_step);
> >
> >       /*
> >        * 3. load instruction to be emulated into relevant register, and
> > @@ -276,7 +276,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe
> > *op, struct kprobe *p)
> >       /*
> >        * 4. branch back from trampoline
> >        */
> > -     patch_branch(buff + TMPL_RET_IDX, (unsigned long)nip, 0);
> > +     patch_branch((void *)(buff + TMPL_RET_IDX), (unsigned long)nip, 0);
>
>
> why do we cast it differently here ?
That is a mistake.
>
>
> >
> >       flush_icache_range((unsigned long)buff,
> >                          (unsigned long)(&buff[TMPL_END_IDX]));
> > @@ -308,7 +308,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe
> > *op)
> >
> >  void arch_optimize_kprobes(struct list_head *oplist)
> >  {
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >       struct optimized_kprobe *op;
> >       struct optimized_kprobe *tmp;
> >
> > @@ -320,9 +320,9 @@ void arch_optimize_kprobes(struct list_head *oplist)
> >               memcpy(op->optinsn.copied_insn, op->kp.addr,
> >                                              RELATIVEJUMP_SIZE);
> >               create_branch(&instr,
> > -                           (unsigned int *)op->kp.addr,
> > +                           (struct ppc_inst *)op->kp.addr,
> >                             (unsigned long)op->optinsn.insn, 0);
> > -             patch_instruction(op->kp.addr, instr);
> > +             patch_instruction((struct ppc_inst *)op->kp.addr, instr);
> >               list_del_init(&op->list);
> >       }
> >  }
> > diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
> > index c1bdd462c5c0..989809e58234 100644
> > --- a/arch/powerpc/kernel/setup_32.c
> > +++ b/arch/powerpc/kernel/setup_32.c
> > @@ -76,7 +76,7 @@ EXPORT_SYMBOL(DMA_MODE_WRITE);
> >  notrace void __init machine_init(u64 dt_ptr)
> >  {
> >       unsigned int *addr = (unsigned int
> > *)patch_site_addr(&patch__memset_nocache);
> > -     unsigned long insn;
> > +     struct ppc_inst insn;
> >
> >       /* Configure static keys first, now that we're relocated. */
> >       setup_feature_keys();
> > diff --git a/arch/powerpc/kernel/trace/ftrace.c
> > b/arch/powerpc/kernel/trace/ftrace.c
> > index 784b5746cc55..442c62fb68ff 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -41,23 +41,23 @@
> >  #define      NUM_FTRACE_TRAMPS       8
> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> >
> > -static unsigned int
> > +static struct ppc_inst
> >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> >  {
> > -     unsigned int op;
> > +     struct ppc_inst op;
> >
> >       addr = ppc_function_entry((void *)addr);
> >
> >       /* if (link) set op to 'bl' else 'b' */
> > -     create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
> > +     create_branch(&op, (struct 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, struct ppc_inst old, struct ppc_inst
> > new)
> >  {
> > -     unsigned int replaced;
> > +     struct ppc_inst replaced;
> >
> >       /*
> >        * Note:
> > @@ -79,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((struct ppc_inst *)ip, new))
> >               return -EPERM;
> >
> >       return 0;
> > @@ -90,24 +90,24 @@ ftrace_modify_code(unsigned long ip, unsigned int old,
> > unsigned int new)
> >   */
> >  static int test_24bit_addr(unsigned long ip, unsigned long addr)
> >  {
> > -     unsigned int op;
> > +     struct ppc_inst op;
> >       addr = ppc_function_entry((void *)addr);
> >
> >       /* use the create_branch to verify that this offset can be branched */
> > -     return create_branch(&op, (unsigned int *)ip, addr, 0) == 0;
> > +     return create_branch(&op, (struct ppc_inst *)ip, addr, 0) == 0;
> >  }
> >
> > -static int is_bl_op(unsigned int op)
> > +static int is_bl_op(struct ppc_inst op)
> >  {
> >       return (ppc_inst_val(op) & 0xfc000003) == 0x48000001;
> >  }
> >
> > -static int is_b_op(unsigned int op)
> > +static int is_b_op(struct ppc_inst op)
> >  {
> >       return (ppc_inst_val(op) & 0xfc000003) == 0x48000000;
> >  }
> >
> > -static unsigned long find_bl_target(unsigned long ip, unsigned int op)
> > +static unsigned long find_bl_target(unsigned long ip, struct ppc_inst op)
> >  {
> >       int offset;
> >
> > @@ -127,7 +127,7 @@ __ftrace_make_nop(struct module *mod,
> >  {
> >       unsigned long entry, ptr, tramp;
> >       unsigned long ip = rec->ip;
> > -     unsigned int op, pop;
> > +     struct ppc_inst op, pop;
> >
> >       /* read where this goes */
> >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > @@ -207,7 +207,7 @@ __ftrace_make_nop(struct module *mod,
> >       }
> >  #endif /* CONFIG_MPROFILE_KERNEL */
> >
> > -     if (patch_instruction((unsigned int *)ip, pop)) {
> > +     if (patch_instruction((struct ppc_inst *)ip, pop)) {
> >               pr_err("Patching NOP failed.\n");
> >               return -EPERM;
> >       }
> > @@ -220,7 +220,7 @@ static int
> >  __ftrace_make_nop(struct module *mod,
> >                 struct dyn_ftrace *rec, unsigned long addr)
> >  {
> > -     unsigned int op;
> > +     struct ppc_inst op;
> >       unsigned int jmp[4];
> >       unsigned long ip = rec->ip;
> >       unsigned long tramp;
> > @@ -279,7 +279,7 @@ __ftrace_make_nop(struct module *mod,
> >
> >       op = ppc_inst(PPC_INST_NOP);
> >
> > -     if (patch_instruction((unsigned int *)ip, op))
> > +     if (patch_instruction((struct ppc_inst *)ip, op))
> >               return -EPERM;
> >
> >       return 0;
> > @@ -290,7 +290,7 @@ __ftrace_make_nop(struct module *mod,
> >  static unsigned long find_ftrace_tramp(unsigned long ip)
> >  {
> >       int i;
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >
> >       /*
> >        * We have the compiler generated long_branch tramps at the end
> > @@ -327,9 +327,10 @@ static int add_ftrace_tramp(unsigned long tramp)
> >   */
> >  static int setup_mcount_compiler_tramp(unsigned long tramp)
> >  {
> > -     int i, op;
> > +     int i;
> > +     struct ppc_inst op;
> >       unsigned long ptr;
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >       static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
> >
> >       /* Is this a known long jump tramp? */
> > @@ -378,7 +379,7 @@ static int setup_mcount_compiler_tramp(unsigned long
> > tramp)
> >               return -1;
> >       }
> >
> > -     if (patch_branch((unsigned int *)tramp, ptr, 0)) {
> > +     if (patch_branch((struct ppc_inst *)tramp, ptr, 0)) {
> >               pr_debug("REL24 out of range!\n");
> >               return -1;
> >       }
> > @@ -394,7 +395,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;
> > +     struct ppc_inst op;
> >
> >       /* Read where this goes */
> >       if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
> > @@ -422,7 +423,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace
> > *rec, unsigned long addr)
> >               }
> >       }
> >
> > -     if (patch_instruction((unsigned int *)ip, ppc_inst(PPC_INST_NOP))) {
> > +     if (patch_instruction((struct ppc_inst *)ip, ppc_inst(PPC_INST_NOP))) {
> >               pr_err("Patching NOP failed.\n");
> >               return -EPERM;
> >       }
> > @@ -434,7 +435,7 @@ int ftrace_make_nop(struct module *mod,
> >                   struct dyn_ftrace *rec, unsigned long addr)
> >  {
> >       unsigned long ip = rec->ip;
> > -     unsigned int old, new;
> > +     struct ppc_inst old, new;
> >
> >       /*
> >        * If the calling address is more that 24 bits away,
> > @@ -487,7 +488,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, struct ppc_inst op0, struct ppc_inst op1)
> >  {
> >       /*
> >        * We expect to see:
> > @@ -504,7 +505,7 @@ expected_nop_sequence(void *ip, unsigned int op0,
> > unsigned int op1)
> >  }
> >  #else
> >  static int
> > -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
> > +expected_nop_sequence(void *ip, struct ppc_inst op0, struct ppc_inst op1)
> >  {
> >       /* look for patched "NOP" on ppc64 with -mprofile-kernel */
> >       if (!ppc_inst_equal(op0, ppc_inst(PPC_INST_NOP)))
> > @@ -516,8 +517,8 @@ 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];
> > -     unsigned int instr;
> > +     struct ppc_inst op[2];
> > +     struct ppc_inst instr;
> >       void *ip = (void *)rec->ip;
> >       unsigned long entry, ptr, tramp;
> >       struct module *mod = rec->arch.mod;
> > @@ -528,7 +529,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_val(op[0]), ppc_inst_val(op[1]));
>
>
> shouldn't this change be part of patch 6,
>
> [PATCH v5 06/21] powerpc: Use an accessor for instructions
Yes it should be.
>
>
> >               return -EINVAL;
> >       }
> >
> > @@ -582,7 +583,7 @@ static int
> >  __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> >  {
> >       int err;
> > -     unsigned int op;
> > +     struct ppc_inst op;
> >       unsigned long ip = rec->ip;
> >
> >       /* read where this goes */
> > @@ -602,7 +603,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long
> > addr)
> >       }
> >
> >       /* create the branch to the trampoline */
> > -     err = create_branch(&op, (unsigned int *)ip,
> > +     err = create_branch(&op, (struct ppc_inst *)ip,
> >                           rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
> >       if (!err) {
> >               pr_err("REL24 out of range!\n");
> > @@ -621,7 +622,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;
> > +     struct ppc_inst op;
> >       void *ip = (void *)rec->ip;
> >       unsigned long tramp, entry, ptr;
> >
> > @@ -669,7 +670,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;
> > +     struct ppc_inst old, new;
> >
> >       /*
> >        * If the calling address is more that 24 bits away,
> > @@ -708,7 +709,7 @@ static int
> >  __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
> >                                       unsigned long addr)
> >  {
> > -     unsigned int op;
> > +     struct ppc_inst op;
> >       unsigned long ip = rec->ip;
> >       unsigned long entry, ptr, tramp;
> >       struct module *mod = rec->arch.mod;
> > @@ -756,7 +757,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((struct ppc_inst *)ip, addr, BRANCH_SET_LINK))
> > {
> >                       pr_err("REL24 out of range!\n");
> >                       return -EINVAL;
> >               }
> > @@ -784,12 +785,12 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned
> > long old_addr,
> >       }
> >
> >       /* Ensure branch is within 24 bits */
> > -     if (create_branch(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> > +     if (create_branch(&op, (struct ppc_inst *)ip, tramp, BRANCH_SET_LINK))
> > {
> >               pr_err("Branch out of range\n");
> >               return -EINVAL;
> >       }
> >
> > -     if (patch_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
> > +     if (patch_branch((struct ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
> >               pr_err("REL24 out of range!\n");
> >               return -EINVAL;
> >       }
> > @@ -802,7 +803,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;
> > +     struct ppc_inst old, new;
> >
> >       /*
> >        * If the calling address is more that 24 bits away,
> > @@ -842,10 +843,10 @@ 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;
> > +     struct ppc_inst old, new;
> >       int ret;
> >
> > -     old = *(unsigned int *)&ftrace_call;
> > +     old = *(struct ppc_inst *)&ftrace_call;
> >       new = ftrace_call_replace(ip, (unsigned long)func, 1);
> >       ret = ftrace_modify_code(ip, old, new);
> >
> > @@ -853,7 +854,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 = *(struct ppc_inst *)&ftrace_regs_call;
> >               new = ftrace_call_replace(ip, (unsigned long)func, 1);
> >               ret = ftrace_modify_code(ip, old, new);
> >       }
> > @@ -927,7 +928,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;
> > +     struct ppc_inst old, new;
> >
> >       old = ftrace_call_replace(ip, stub, 0);
> >       new = ftrace_call_replace(ip, addr, 0);
> > @@ -940,7 +941,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;
> > +     struct ppc_inst old, new;
> >
> >       old = ftrace_call_replace(ip, addr, 0);
> >       new = ftrace_call_replace(ip, stub, 0);
> > diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c
> > index c8d21e812d8c..bbf536e10902 100644
> > --- a/arch/powerpc/kernel/vecemu.c
> > +++ b/arch/powerpc/kernel/vecemu.c
> > @@ -261,11 +261,12 @@ static unsigned int rfin(unsigned int x)
> >
> >  int emulate_altivec(struct pt_regs *regs)
> >  {
> > -     unsigned int instr, i, word;
> > +     struct ppc_inst instr;
> > +     unsigned int i, word;
> >       unsigned int va, vb, vc, vd;
> >       vector128 *vrs;
> >
> > -     if (get_user(instr, (unsigned int __user *) regs->nip))
> > +     if (get_user(instr.val, (unsigned int __user *) regs->nip))
>
>
> [...] reference to above for using helper.
>
>
> >               return -EFAULT;
> >
> >       word = ppc_inst_val(instr);
> > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > patching.c
> > index 33654c6334a9..91be4a0b51cb 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -19,12 +19,12 @@
> >  #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(struct ppc_inst *exec_addr, struct ppc_inst
> > instr,
> > +                            struct ppc_inst *patch_addr)
> >  {
> >       int err = 0;
> >
> > -     __put_user_asm(instr, patch_addr, err, "stw");
> > +     __put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw");
> >       if (err)
> >               return err;
> >
> > @@ -34,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(struct ppc_inst *addr, struct ppc_inst instr)
> >  {
> >       return __patch_instruction(addr, instr, addr);
> >  }
> > @@ -137,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(struct ppc_inst *addr, struct ppc_inst
> > instr)
> >  {
> >       int err;
> > -     unsigned int *patch_addr = NULL;
> > +     struct ppc_inst *patch_addr = NULL;
> >       unsigned long flags;
> >       unsigned long text_poke_addr;
> >       unsigned long kaddr = (unsigned long)addr;
> > @@ -177,14 +177,14 @@ 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(struct ppc_inst *addr, struct ppc_inst
> > instr)
> >  {
> >       return raw_patch_instruction(addr, instr);
> >  }
> >
> >  #endif /* CONFIG_STRICT_KERNEL_RWX */
> >
> > -int patch_instruction(unsigned int *addr, unsigned int instr)
> > +int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr)
> >  {
> >       /* Make sure we aren't patching a freed init section */
> >       if (init_mem_is_free && init_section_contains(addr, 4)) {
> > @@ -195,9 +195,9 @@ 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(struct ppc_inst *addr, unsigned long target, int flags)
> >  {
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >
> >       create_branch(&instr, addr, target, flags);
> >       return patch_instruction(addr, instr);
> > @@ -229,7 +229,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(struct ppc_inst instr)
> >  {
> >       unsigned int opcode = ppc_inst_opcode(instr);
> >
> > @@ -247,13 +247,13 @@ bool is_conditional_branch(unsigned int instr)
> >  }
> >  NOKPROBE_SYMBOL(is_conditional_branch);
> >
> > -int create_branch(unsigned int *instr,
> > -               const unsigned int *addr,
> > +int create_branch(struct ppc_inst *instr,
> > +               const struct ppc_inst *addr,
> >                 unsigned long target, int flags)
> >  {
> >       long offset;
> >
> > -     *instr = 0;
> > +     *instr = ppc_inst(0);
> >       offset = target;
> >       if (! (flags & BRANCH_ABSOLUTE))
> >               offset = offset - (unsigned long)addr;
> > @@ -263,12 +263,12 @@ int create_branch(unsigned int *instr,
> >               return 1;
> >
> >       /* Mask out the flags and target, so they don't step on each other. */
> > -     *instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
> > +     *instr = ppc_inst(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC));
> >
> >       return 0;
> >  }
> >
> > -int create_cond_branch(unsigned int *instr, const unsigned int *addr,
> > +int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
> >                      unsigned long target, int flags)
> >  {
> >       long offset;
> > @@ -282,27 +282,27 @@ int create_cond_branch(unsigned int *instr, const
> > unsigned int *addr,
> >               return 1;
> >
> >       /* Mask out the flags and target, so they don't step on each other. */
> > -     *instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
> > +     *instr = ppc_inst(0x40000000 | (flags & 0x3FF0003) | (offset &
> > 0xFFFC));
> >
> >       return 0;
> >  }
> >
> > -static unsigned int branch_opcode(unsigned int instr)
> > +static unsigned int branch_opcode(struct ppc_inst instr)
> >  {
> >       return ppc_inst_opcode(instr) & 0x3F;
> >  }
> >
> > -static int instr_is_branch_iform(unsigned int instr)
> > +static int instr_is_branch_iform(struct ppc_inst instr)
> >  {
> >       return branch_opcode(instr) == 18;
> >  }
> >
> > -static int instr_is_branch_bform(unsigned int instr)
> > +static int instr_is_branch_bform(struct ppc_inst instr)
> >  {
> >       return branch_opcode(instr) == 16;
> >  }
> >
> > -int instr_is_relative_branch(unsigned int instr)
> > +int instr_is_relative_branch(struct ppc_inst instr)
> >  {
> >       if (ppc_inst_val(instr) & BRANCH_ABSOLUTE)
> >               return 0;
> > @@ -310,12 +310,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(struct ppc_inst instr)
> >  {
> >       return instr_is_relative_branch(instr) && (ppc_inst_val(instr) &
> > BRANCH_SET_LINK);
> >  }
> >
> > -static unsigned long branch_iform_target(const unsigned int *instr)
> > +static unsigned long branch_iform_target(const struct ppc_inst *instr)
> >  {
> >       signed long imm;
> >
> > @@ -331,7 +331,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 struct ppc_inst *instr)
> >  {
> >       signed long imm;
> >
> > @@ -347,7 +347,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 struct ppc_inst *instr)
> >  {
> >       if (instr_is_branch_iform(*instr))
> >               return branch_iform_target(instr);
> > @@ -357,7 +357,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 struct ppc_inst *instr, unsigned long
> > addr)
> >  {
> >       if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
> >               return branch_target(instr) == addr;
> > @@ -365,7 +365,7 @@ int instr_is_branch_to_addr(const unsigned int *instr,
> > unsigned long addr)
> >       return 0;
> >  }
> >
> > -int translate_branch(unsigned int *instr, const unsigned int *dest, const
> > unsigned int *src)
> > +int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
> > const struct ppc_inst *src)
> >  {
> >       unsigned long target;
> >
> > @@ -408,7 +408,7 @@ static void __init test_trampoline(void)
> >  static void __init test_branch_iform(void)
> >  {
> >       int err;
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >       unsigned long addr;
> >
> >       addr = (unsigned long)&instr;
> > @@ -483,12 +483,12 @@ static void __init test_branch_iform(void)
> >
> >  static void __init test_create_function_call(void)
> >  {
> > -     unsigned int *iptr;
> > +     struct ppc_inst *iptr;
> >       unsigned long dest;
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >
> >       /* Check we can create a function call */
> > -     iptr = (unsigned int *)ppc_function_entry(test_trampoline);
> > +     iptr = (struct ppc_inst *)ppc_function_entry(test_trampoline);
> >       dest = ppc_function_entry(test_create_function_call);
> >       create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
> >       patch_instruction(iptr, instr);
> > @@ -499,7 +499,8 @@ static void __init test_branch_bform(void)
> >  {
> >       int err;
> >       unsigned long addr;
> > -     unsigned int *iptr, instr, flags;
> > +     struct ppc_inst *iptr, instr;
> > +     unsigned int flags;
> >
> >       iptr = &instr;
> >       addr = (unsigned long)iptr;
> > @@ -569,8 +570,8 @@ static void __init test_branch_bform(void)
> >  static void __init test_translate_branch(void)
> >  {
> >       unsigned long addr;
> > -     unsigned int *p, *q;
> > -     unsigned int instr;
> > +     struct ppc_inst *p, *q;
> > +     struct ppc_inst instr;
> >       void *buf;
> >
> >       buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
> > diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> > fixups.c
> > index 6e7479b8887a..8c5d0db77013 100644
> > --- a/arch/powerpc/lib/feature-fixups.c
> > +++ b/arch/powerpc/lib/feature-fixups.c
> > @@ -32,26 +32,26 @@ struct fixup_entry {
> >       long            alt_end_off;
> >  };
> >
> > -static unsigned int *calc_addr(struct fixup_entry *fcur, long offset)
> > +static struct ppc_inst *calc_addr(struct fixup_entry *fcur, long offset)
> >  {
> >       /*
> >        * We store the offset to the code as a negative offset from
> >        * the start of the alt_entry, to support the VDSO. This
> >        * routine converts that back into an actual address.
> >        */
> > -     return (unsigned int *)((unsigned long)fcur + offset);
> > +     return (struct ppc_inst *)((unsigned long)fcur + offset);
> >  }
> >
> > -static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
> > -                              unsigned int *alt_start, unsigned int
> > *alt_end)
> > +static int patch_alt_instruction(struct ppc_inst *src, struct ppc_inst
> > *dest,
> > +                              struct ppc_inst *alt_start, struct ppc_inst
> > *alt_end)
> >  {
> >       int err;
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >
> >       instr = *src;
> >
> >       if (instr_is_relative_branch(*src)) {
> > -             unsigned int *target = (unsigned int *)branch_target(src);
> > +             struct ppc_inst *target = (struct ppc_inst
> > *)branch_target(src);
> >
> >               /* Branch within the section doesn't need translating */
> >               if (target < alt_start || target > alt_end) {
> > @@ -68,7 +68,7 @@ static int patch_alt_instruction(unsigned int *src,
> > unsigned int *dest,
> >
> >  static int patch_feature_section(unsigned long value, struct fixup_entry
> > *fcur)
> >  {
> > -     unsigned int *start, *end, *alt_start, *alt_end, *src, *dest;
> > +     struct ppc_inst *start, *end, *alt_start, *alt_end, *src, *dest;
> >
> >       start = calc_addr(fcur, fcur->start_off);
> >       end = calc_addr(fcur, fcur->end_off);
> > @@ -147,15 +147,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, ppc_inst(instrs[0]));
> > +             patch_instruction((struct ppc_inst *)dest,
> > ppc_inst(instrs[0]));
>
>
> we had already declared them as struct ppc_inst *
True.
>
>
> >
> >               if (types & STF_BARRIER_FALLBACK)
> > -                     patch_branch(dest + 1, (unsigned
> > long)&stf_barrier_fallback,
> > +                     patch_branch((struct ppc_inst *)(dest + 1), (unsigned
> > long)&stf_barrier_fallback,
> >                                    BRANCH_SET_LINK);
> >               else
> > -                     patch_instruction(dest + 1, ppc_inst(instrs[1]));
> > +                     patch_instruction((struct ppc_inst *)(dest + 1),
> > ppc_inst(instrs[1]));
> >
> > -             patch_instruction(dest + 2, ppc_inst(instrs[2]));
> > +             patch_instruction((struct ppc_inst *)(dest + 2),
> > ppc_inst(instrs[2]));
> >       }
> >
> >       printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s
> > barrier)\n", i,
> > @@ -208,12 +208,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, 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]));
> > +             patch_instruction((struct ppc_inst *)dest,
> > ppc_inst(instrs[0]));
> > +             patch_instruction((struct ppc_inst *)(dest + 1),
> > ppc_inst(instrs[1]));
> > +             patch_instruction((struct ppc_inst *)(dest + 2),
> > ppc_inst(instrs[2]));
> > +             patch_instruction((struct ppc_inst *)(dest + 3),
> > ppc_inst(instrs[3]));
> > +             patch_instruction((struct ppc_inst *)(dest + 4),
> > ppc_inst(instrs[4]));
> > +             patch_instruction((struct ppc_inst *)(dest + 5),
> > ppc_inst(instrs[5]));
> >       }
> >       printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s
> > barrier)\n", i,
> >               (types == STF_BARRIER_NONE)                  ? "no" :
> > @@ -261,9 +261,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
> >
> >               pr_devel("patching dest %lx\n", (unsigned long)dest);
> >
> > -             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((struct ppc_inst *)dest,
> > ppc_inst(instrs[0]));
> > +             patch_instruction((struct ppc_inst *)(dest + 1),
> > ppc_inst(instrs[1]));
> > +             patch_instruction((struct ppc_inst *)(dest + 2),
> > ppc_inst(instrs[2]));
> >       }
> >
> >       printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
> > @@ -296,7 +296,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, ppc_inst(instr));
> > +             patch_instruction((struct ppc_inst *)dest, ppc_inst(instr));
> >       }
> >
> >       printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
> > @@ -339,8 +339,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, ppc_inst(instr[0]));
> > -             patch_instruction(dest + 1, ppc_inst(instr[1]));
> > +             patch_instruction((struct ppc_inst *)dest, ppc_inst(instr[0]));
> > +             patch_instruction((struct ppc_inst *)(dest + 1),
> > ppc_inst(instr[1]));
> >       }
> >
> >       printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
> > @@ -373,7 +373,7 @@ void do_btb_flush_fixups(void)
> >  void do_lwsync_fixups(unsigned long value, void *fixup_start, void
> > *fixup_end)
> >  {
> >       long *start, *end;
> > -     unsigned int *dest;
> > +     struct ppc_inst *dest;
> >
> >       if (!(value & CPU_FTR_LWSYNC))
> >               return ;
> > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > index 26e37176692e..52ddd3122dc8 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)
> > +               struct ppc_inst instr)
>
>
> we need to take care of `instr` inside this function as well to adopt
> the helpers to work with it.
>
> -- Bala
>
>
> >  {
> >       unsigned int opcode, ra, rb, rc, rd, spr, u;
> >       unsigned long int imm;
> > @@ -3103,7 +3103,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, struct 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 16387a9bfda0..60b159b60545 100644
> > --- a/arch/powerpc/lib/test_emulate_step.c
> > +++ b/arch/powerpc/lib/test_emulate_step.c
> > @@ -461,7 +461,7 @@ struct compute_test {
> >       struct {
> >               char *descr;
> >               unsigned long flags;
> > -             unsigned int instr;
> > +             struct ppc_inst instr;
> >               struct pt_regs regs;
> >       } subtests[MAX_SUBTESTS + 1];
> >  };
> > @@ -842,7 +842,7 @@ static struct compute_test compute_tests[] = {
> >  };
> >
> >  static int __init emulate_compute_instr(struct pt_regs *regs,
> > -                                     unsigned int instr)
> > +                                     struct ppc_inst instr)
> >  {
> >       struct instruction_op op;
> >
> > @@ -860,7 +860,7 @@ static int __init emulate_compute_instr(struct pt_regs
> > *regs,
> >  }
> >
> >  static int __init execute_compute_instr(struct pt_regs *regs,
> > -                                     unsigned int instr)
> > +                                     struct ppc_inst instr)
> >  {
> >       extern int exec_instr(struct pt_regs *regs);
> >       extern s32 patch__exec_instr;
> > @@ -891,7 +891,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;
> > +     struct 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/perf/core-book3s.c b/arch/powerpc/perf/core-
> > book3s.c
> > index 3086055bf681..2d2580a4bfb5 100644
> > --- a/arch/powerpc/perf/core-book3s.c
> > +++ b/arch/powerpc/perf/core-book3s.c
> > @@ -421,14 +421,14 @@ static __u64 power_pmu_bhrb_to(u64 addr)
> >               if (probe_kernel_read(&instr, (void *)addr, sizeof(instr)))
> >                       return 0;
> >
> > -             return branch_target(&instr);
> > +             return branch_target((struct ppc_inst *)&instr);
> >       }
> >
> >       /* Userspace: need copy instruction here then translate it */
> >       if (probe_user_read(&instr, (unsigned int __user *)addr,
> > sizeof(instr)))
> >               return 0;
> >
> > -     target = branch_target(&instr);
> > +     target = branch_target((struct ppc_inst *)&instr);
> >       if ((!target) || (instr & BRANCH_ABSOLUTE))
> >               return target;
> >
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index f6c87d3d53ea..e3d8e1b8ce01 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -99,7 +99,7 @@ static long *xmon_fault_jmp[NR_CPUS];
> >  /* Breakpoint stuff */
> >  struct bpt {
> >       unsigned long   address;
> > -     unsigned int    *instr;
> > +     struct ppc_inst *instr;
> >       atomic_t        ref_count;
> >       int             enabled;
> >       unsigned long   pad;
> > @@ -117,7 +117,7 @@ static unsigned bpinstr = 0x7fe00008;     /* trap */
> >
> >  #define BP_NUM(bp)   ((bp) - bpts + 1)
> >
> > -#define BPT_SIZE     (sizeof(unsigned int) * 2)
> > +#define BPT_SIZE     (sizeof(struct ppc_inst) * 2)
> >  #define BPT_WORDS    (BPT_SIZE / sizeof(unsigned int))
> >  extern unsigned int bpt_table[NBPTS * BPT_WORDS];
> >
> > @@ -879,8 +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;
> > -                     bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
> > -                     patch_instruction(bp->instr + 1, bpinstr);
> > +                     bp->instr = (void *)(bpt_table + ((bp - bpts) *
> > BPT_WORDS));
> > +                     patch_instruction(bp->instr + 1, ppc_inst(bpinstr));
> >                       return bp;
> >               }
> >       }
> > @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a)
> >  static void insert_bpts(void)
> >  {
> >       int i;
> > -     unsigned int instr;
> > +     struct ppc_inst instr;
> >       struct bpt *bp;
> >
> >       bp = bpts;
> > @@ -914,8 +914,8 @@ static void insert_bpts(void)
> >               patch_instruction(bp->instr, instr);
> >               if (bp->enabled & BP_CIABR)
> >                       continue;
> > -             if (patch_instruction((unsigned int *)bp->address,
> > -                                                     bpinstr) != 0) {
> > +             if (patch_instruction((struct ppc_inst *)bp->address,
> > +                                                     ppc_inst(bpinstr)) !=
> > 0) {
> >                       printf("Couldn't write instruction at %lx, "
> >                              "disabling breakpoint there\n", bp->address);
> >                       bp->enabled &= ~BP_TRAP;
> > @@ -943,7 +943,7 @@ static void remove_bpts(void)
> >  {
> >       int i;
> >       struct bpt *bp;
> > -     unsigned instr;
> > +     struct 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
> >                   && ppc_inst_equal(instr, ppc_inst(bpinstr))
> >                   && patch_instruction(
> > -                     (unsigned int *)bp->address, bp->instr[0]) != 0)
> > +                     (struct 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;
> > +     struct 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;
> > +     struct ppc_inst instr;
> >
> >       addr &= ~3;
> >       if (!is_kernel_addr(addr)) {
> > @@ -2846,7 +2846,7 @@ generic_inst_dump(unsigned long adr, long count, int
> > praddr,
> >  {
> >       int nr, dotted;
> >       unsigned long first_adr;
> > -     unsigned int inst, last_inst = ppc_inst(0);
> > +     struct ppc_inst inst, last_inst = ppc_inst(0);
> >       unsigned char val[4];
> >
> >       dotted = 0;
>

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

* Re: [PATCH v5 11/21] powerpc: Define and use __get_user_instr{, inatomic}()
  2020-04-07 10:48   ` Balamuruhan S
@ 2020-04-08  2:13     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-08  2:13 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Tue, Apr 7, 2020 at 8:48 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > Define specific __get_user_instr() and __get_user_instr_inatomic()
> > macros for reading instructions from user space.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> >  arch/powerpc/include/asm/uaccess.h  | 5 +++++
> >  arch/powerpc/kernel/align.c         | 2 +-
> >  arch/powerpc/kernel/hw_breakpoint.c | 2 +-
> >  arch/powerpc/kernel/vecemu.c        | 2 +-
> >  4 files changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/uaccess.h
> > b/arch/powerpc/include/asm/uaccess.h
> > index 2f500debae21..c0a35e4586a5 100644
> > --- a/arch/powerpc/include/asm/uaccess.h
> > +++ b/arch/powerpc/include/asm/uaccess.h
> > @@ -105,6 +105,11 @@ 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)))
> >
> > +#define __get_user_instr(x, ptr) \
> > +     __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> > +
> > +#define __get_user_instr_inatomic(x, ptr) \
> > +     __get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
>
>
> should we use ppc_inst_val() ?
The __get_user() macros load a value into the given variable, so we
can not use ppc_inst_val().
>
> -- Bala
>
>
> >  extern long __put_user_bad(void);
> >
> >  /*
> > diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> > index 66a6d1de7799..65cdfd41e3a1 100644
> > --- a/arch/powerpc/kernel/align.c
> > +++ b/arch/powerpc/kernel/align.c
> > @@ -304,7 +304,7 @@ int fix_alignment(struct pt_regs *regs)
> >        */
> >       CHECK_FULL_REGS(regs);
> >
> > -     if (unlikely(__get_user(instr.val, (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... */
> > diff --git a/arch/powerpc/kernel/hw_breakpoint.c
> > b/arch/powerpc/kernel/hw_breakpoint.c
> > index 542f65ccf68b..cebab14e2788 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.val, (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/vecemu.c b/arch/powerpc/kernel/vecemu.c
> > index bbf536e10902..c82ede46d71b 100644
> > --- a/arch/powerpc/kernel/vecemu.c
> > +++ b/arch/powerpc/kernel/vecemu.c
> > @@ -266,7 +266,7 @@ int emulate_altivec(struct pt_regs *regs)
> >       unsigned int va, vb, vc, vd;
> >       vector128 *vrs;
> >
> > -     if (get_user(instr.val, (unsigned int __user *) regs->nip))
> > +     if (__get_user_instr(instr, (void __user *) regs->nip))
> >               return -EFAULT;
> >
> >       word = ppc_inst_val(instr);
>

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

* Re: [PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length
  2020-04-07 11:14   ` Balamuruhan S
@ 2020-04-08  2:14     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-08  2:14 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

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

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

* Re: [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions
  2020-04-07 11:30   ` Balamuruhan S
@ 2020-04-08  2:18     ` Jordan Niethe
  2020-04-09  5:04       ` Balamuruhan S
  0 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-08  2:18 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Tue, Apr 7, 2020 at 9:31 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > Currently in xmon, mread() is used for reading instructions. In
> > preparation for prefixed instructions, create and use a new function,
> > mread_instr(), especially for reading instructions.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> > v5: New to series, seperated from "Add prefixed instructions to
> > instruction data type"
> > ---
> >  arch/powerpc/xmon/xmon.c | 24 ++++++++++++++++++++----
> >  1 file changed, 20 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index 5e3949322a6c..6f4cf01a58c1 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -125,6 +125,7 @@ extern unsigned int bpt_table[NBPTS * BPT_WORDS];
> >  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, struct ppc_inst *);
> >  static int handle_fault(struct pt_regs *);
> >  static void byterev(unsigned char *, int);
> >  static void memex(void);
> > @@ -899,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)) {
>
>
> Are these checks made based on whether `ppc_inst_len()` returns bool from
> mread_instr() ?
No, it was meant to be the length itself returned with a length of 0
indicating an error. I will need to fix that.
>
> -- Bala
>
>
> >                       printf("Couldn't read instruction at %lx, "
> >                              "disabling breakpoint there\n", bp->address);
> >                       bp->enabled = 0;
> > @@ -949,7 +950,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(
> >                       (struct ppc_inst *)bp->address, ppc_inst_read(bp-
> > >instr)) != 0)
> > @@ -1165,7 +1166,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",
> > @@ -1332,7 +1333,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;
> >       }
> > @@ -2125,6 +2126,21 @@ mwrite(unsigned long adrs, void *buf, int size)
> >       return n;
> >  }
> >
> > +static int
> > +mread_instr(unsigned long adrs, struct ppc_inst *instr)
> > +{
> > +     if (setjmp(bus_error_jmp) == 0) {
> > +             catch_memory_errors = 1;
> > +             sync();
> > +             *instr = ppc_inst_read((struct ppc_inst *)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] 71+ messages in thread

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06 10:25     ` Christophe Leroy
  2020-04-06 11:13       ` Jordan Niethe
@ 2020-04-08 18:11       ` Segher Boessenkool
  2020-04-08 18:43         ` Christophe Leroy
  1 sibling, 1 reply; 71+ messages in thread
From: Segher Boessenkool @ 2020-04-08 18:11 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Alistair Popple, npiggin, bala24, Jordan Niethe, linuxppc-dev, dja

On Mon, Apr 06, 2020 at 12:25:27PM +0200, Christophe Leroy wrote:
> >	if (ppc_inst_prefixed(x) != ppc_inst_prefixed(y))
> >		return false;
> >	else if (ppc_inst_prefixed(x))
> >		return !memcmp(&x, &y, sizeof(struct ppc_inst));
> 
> Are we sure memcmp() is a good candidate for the comparison ? Can we do 
> simpler ? Especially, I understood a prefixed instruction is a 64 bits 
> properly aligned instruction, can we do a simple u64 compare ? Or is GCC 
> intelligent enough to do that without calling memcmp() function which is 
> heavy ?

A prefixed insn is *not* 8-byte aligned, it is 4-byte aligned, fwiw.

memcmp() isn't as heavy as you fear, not with a non-ancient GCC at least.
But this could be written in a nicer way, sure :-)


Segher

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

* Re: [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code
  2020-04-06  8:09 ` [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code Jordan Niethe
  2020-04-06  8:22   ` Christophe Leroy
  2020-04-07  7:04   ` Balamuruhan S
@ 2020-04-08 18:21   ` Segher Boessenkool
  2020-04-09  4:48     ` Jordan Niethe
  2 siblings, 1 reply; 71+ messages in thread
From: Segher Boessenkool @ 2020-04-08 18:21 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: alistair, dja, linuxppc-dev, npiggin, bala24

Hi!

On Mon, Apr 06, 2020 at 06:09:20PM +1000, Jordan Niethe wrote:
> +static inline int ppc_inst_opcode(u32 x)
> +{
> +	return x >> 26;
> +}

Maybe you should have "primary opcode" in this function name?


Segher

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-08 18:11       ` Segher Boessenkool
@ 2020-04-08 18:43         ` Christophe Leroy
  0 siblings, 0 replies; 71+ messages in thread
From: Christophe Leroy @ 2020-04-08 18:43 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Alistair Popple, npiggin, bala24, Jordan Niethe, linuxppc-dev, dja



Le 08/04/2020 à 20:11, Segher Boessenkool a écrit :
> On Mon, Apr 06, 2020 at 12:25:27PM +0200, Christophe Leroy wrote:
>>> 	if (ppc_inst_prefixed(x) != ppc_inst_prefixed(y))
>>> 		return false;
>>> 	else if (ppc_inst_prefixed(x))
>>> 		return !memcmp(&x, &y, sizeof(struct ppc_inst));
>>
>> Are we sure memcmp() is a good candidate for the comparison ? Can we do
>> simpler ? Especially, I understood a prefixed instruction is a 64 bits
>> properly aligned instruction, can we do a simple u64 compare ? Or is GCC
>> intelligent enough to do that without calling memcmp() function which is
>> heavy ?
> 
> A prefixed insn is *not* 8-byte aligned, it is 4-byte aligned, fwiw.

Ah, yes, I read too fast https://patchwork.ozlabs.org/patch/1266721/

It's not 64 bits, it is 64 bytes.

> 
> memcmp() isn't as heavy as you fear, not with a non-ancient GCC at least.
> But this could be written in a nicer way, sure :-)
> 
> 
> Segher
> 

Christophe

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

* Re: [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code
  2020-04-08 18:21   ` Segher Boessenkool
@ 2020-04-09  4:48     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-09  4:48 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Alistair Popple, Daniel Axtens, linuxppc-dev, Nicholas Piggin,
	Balamuruhan S

On Thu, Apr 9, 2020 at 4:21 AM Segher Boessenkool
<segher@kernel.crashing.org> wrote:
>
> Hi!
>
> On Mon, Apr 06, 2020 at 06:09:20PM +1000, Jordan Niethe wrote:
> > +static inline int ppc_inst_opcode(u32 x)
> > +{
> > +     return x >> 26;
> > +}
>
> Maybe you should have "primary opcode" in this function name?
Thanks, that is a good idea.
>
>
> Segher

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

* Re: [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions
  2020-04-08  2:18     ` Jordan Niethe
@ 2020-04-09  5:04       ` Balamuruhan S
  2020-04-09  5:14         ` Jordan Niethe
  0 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-09  5:04 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Wed, 2020-04-08 at 12:18 +1000, Jordan Niethe wrote:
> On Tue, Apr 7, 2020 at 9:31 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
> > On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > > Currently in xmon, mread() is used for reading instructions. In
> > > preparation for prefixed instructions, create and use a new function,
> > > mread_instr(), especially for reading instructions.
> > > 
> > > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > > ---
> > > v5: New to series, seperated from "Add prefixed instructions to
> > > instruction data type"
> > > ---
> > >  arch/powerpc/xmon/xmon.c | 24 ++++++++++++++++++++----
> > >  1 file changed, 20 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > > index 5e3949322a6c..6f4cf01a58c1 100644
> > > --- a/arch/powerpc/xmon/xmon.c
> > > +++ b/arch/powerpc/xmon/xmon.c
> > > @@ -125,6 +125,7 @@ extern unsigned int bpt_table[NBPTS * BPT_WORDS];
> > >  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, struct ppc_inst *);
> > >  static int handle_fault(struct pt_regs *);
> > >  static void byterev(unsigned char *, int);
> > >  static void memex(void);
> > > @@ -899,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)) {
> > 
> > Are these checks made based on whether `ppc_inst_len()` returns bool from
> > mread_instr() ?
> No, it was meant to be the length itself returned with a length of 0
> indicating an error. I will need to fix that.


I doubt it would return 0, whether we read instruction or not ppc_inst_len()
would always return sizeof(struct ppc_inst).

can we do something like,

static int
mread_instr(unsigned long adrs, struct ppc_inst *instr)
{
	int size = 0;
	if (setjmp(bus_error_jmp) == 0) {
		catch_memory_errors = 1;
		sync();
		*instr = ppc_inst_read((struct ppc_inst *)adrs);
		sync();
		/* wait a little while to see if we get a machine check */
		__delay(200);
		size = ppc_inst_len(instr);
	}
	catch_memory_errors = 0;
	return size;
}

-- Bala
> > -- Bala
> > 
> > 
> > >                       printf("Couldn't read instruction at %lx, "
> > >                              "disabling breakpoint there\n", bp-
> > > >address);
> > >                       bp->enabled = 0;
> > > @@ -949,7 +950,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(
> > >                       (struct ppc_inst *)bp->address, ppc_inst_read(bp-
> > > > instr)) != 0)
> > > @@ -1165,7 +1166,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",
> > > @@ -1332,7 +1333,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;
> > >       }
> > > @@ -2125,6 +2126,21 @@ mwrite(unsigned long adrs, void *buf, int size)
> > >       return n;
> > >  }
> > > 
> > > +static int
> > > +mread_instr(unsigned long adrs, struct ppc_inst *instr)
> > > +{
> > > +     if (setjmp(bus_error_jmp) == 0) {
> > > +             catch_memory_errors = 1;
> > > +             sync();
> > > +             *instr = ppc_inst_read((struct ppc_inst *)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] 71+ messages in thread

* Re: [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions
  2020-04-09  5:04       ` Balamuruhan S
@ 2020-04-09  5:14         ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-09  5:14 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Thu, Apr 9, 2020 at 3:04 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Wed, 2020-04-08 at 12:18 +1000, Jordan Niethe wrote:
> > On Tue, Apr 7, 2020 at 9:31 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
> > > On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > > > Currently in xmon, mread() is used for reading instructions. In
> > > > preparation for prefixed instructions, create and use a new function,
> > > > mread_instr(), especially for reading instructions.
> > > >
> > > > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > > > ---
> > > > v5: New to series, seperated from "Add prefixed instructions to
> > > > instruction data type"
> > > > ---
> > > >  arch/powerpc/xmon/xmon.c | 24 ++++++++++++++++++++----
> > > >  1 file changed, 20 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > > > index 5e3949322a6c..6f4cf01a58c1 100644
> > > > --- a/arch/powerpc/xmon/xmon.c
> > > > +++ b/arch/powerpc/xmon/xmon.c
> > > > @@ -125,6 +125,7 @@ extern unsigned int bpt_table[NBPTS * BPT_WORDS];
> > > >  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, struct ppc_inst *);
> > > >  static int handle_fault(struct pt_regs *);
> > > >  static void byterev(unsigned char *, int);
> > > >  static void memex(void);
> > > > @@ -899,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)) {
> > >
> > > Are these checks made based on whether `ppc_inst_len()` returns bool from
> > > mread_instr() ?
> > No, it was meant to be the length itself returned with a length of 0
> > indicating an error. I will need to fix that.
>
>
> I doubt it would return 0, whether we read instruction or not ppc_inst_len()
> would always return sizeof(struct ppc_inst).
Yes, sorry I meant I would have to change the function so that it
would return 0.
>
> can we do something like,
>
> static int
> mread_instr(unsigned long adrs, struct ppc_inst *instr)
> {
>         int size = 0;
>         if (setjmp(bus_error_jmp) == 0) {
>                 catch_memory_errors = 1;
>                 sync();
>                 *instr = ppc_inst_read((struct ppc_inst *)adrs);
>                 sync();
>                 /* wait a little while to see if we get a machine check */
>                 __delay(200);
>                 size = ppc_inst_len(instr);
>         }
>         catch_memory_errors = 0;
>         return size;
> }
Yeah that looks right.
>
> -- Bala
> > > -- Bala
> > >
> > >
> > > >                       printf("Couldn't read instruction at %lx, "
> > > >                              "disabling breakpoint there\n", bp-
> > > > >address);
> > > >                       bp->enabled = 0;
> > > > @@ -949,7 +950,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(
> > > >                       (struct ppc_inst *)bp->address, ppc_inst_read(bp-
> > > > > instr)) != 0)
> > > > @@ -1165,7 +1166,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",
> > > > @@ -1332,7 +1333,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;
> > > >       }
> > > > @@ -2125,6 +2126,21 @@ mwrite(unsigned long adrs, void *buf, int size)
> > > >       return n;
> > > >  }
> > > >
> > > > +static int
> > > > +mread_instr(unsigned long adrs, struct ppc_inst *instr)
> > > > +{
> > > > +     if (setjmp(bus_error_jmp) == 0) {
> > > > +             catch_memory_errors = 1;
> > > > +             sync();
> > > > +             *instr = ppc_inst_read((struct ppc_inst *)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] 71+ messages in thread

* Re: [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section
  2020-04-06  8:09 ` [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section Jordan Niethe
  2020-04-07  6:45   ` Balamuruhan S
@ 2020-04-09  6:11   ` Christophe Leroy
  2020-04-09  7:26     ` Jordan Niethe
  1 sibling, 1 reply; 71+ messages in thread
From: Christophe Leroy @ 2020-04-09  6:11 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: bala24, alistair, dja, npiggin



Le 06/04/2020 à 10:09, Jordan Niethe a écrit :
> 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
> v5: - Do not use __section(), use a .space directive in .S file

I was going to comment to use __section() instead of creating a 
dedicated .S file.

Why did you change that in v5 ?

>      - Simplify in_breakpoint_table() calculation
>      - Define BPT_SIZE
> ---
>   arch/powerpc/xmon/Makefile    |  2 +-
>   arch/powerpc/xmon/xmon.c      | 23 +++++++++++++----------
>   arch/powerpc/xmon/xmon_bpts.S |  8 ++++++++
>   arch/powerpc/xmon/xmon_bpts.h |  8 ++++++++
>   4 files changed, 30 insertions(+), 11 deletions(-)
>   create mode 100644 arch/powerpc/xmon/xmon_bpts.S
>   create mode 100644 arch/powerpc/xmon/xmon_bpts.h
> 
> diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
> index c3842dbeb1b7..515a13ea6f28 100644
> --- a/arch/powerpc/xmon/Makefile
> +++ b/arch/powerpc/xmon/Makefile
> @@ -21,7 +21,7 @@ endif
>   
>   ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
>   
> -obj-y			+= xmon.o nonstdio.o spr_access.o
> +obj-y			+= xmon.o nonstdio.o spr_access.o xmon_bpts.o
>   
>   ifdef CONFIG_XMON_DISASSEMBLY
>   obj-y			+= ppc-dis.o ppc-opc.o
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 02e3bd62cab4..049375206510 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -62,6 +62,7 @@
>   
>   #include "nonstdio.h"
>   #include "dis-asm.h"
> +#include "xmon_bpts.h"
>   
>   #ifdef CONFIG_SMP
>   static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
> @@ -97,7 +98,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;
> @@ -108,7 +109,6 @@ struct bpt {
>   #define BP_TRAP		2
>   #define BP_DABR		4
>   
> -#define NBPTS	256
>   static struct bpt bpts[NBPTS];
>   static struct bpt dabr;
>   static struct bpt *iabr;
> @@ -116,6 +116,10 @@ static unsigned bpinstr = 0x7fe00008;	/* trap */
>   
>   #define BP_NUM(bp)	((bp) - bpts + 1)
>   
> +#define BPT_SIZE	(sizeof(unsigned int) * 2)
> +#define BPT_WORDS	(BPT_SIZE / sizeof(unsigned int))

Wouldn't it make more sense to do the following ? :

#define BPT_WORDS	2
#define BPT_SIZE 	(BPT_WORDS * sizeof(unsigned int))

> +extern unsigned int bpt_table[NBPTS * BPT_WORDS];

Should go in xmon_bpts.h if we keep the definition in xmon_bpts.S

> +
>   /* Prototypes */
>   static int cmds(struct pt_regs *);
>   static int mread(unsigned long, void *, int);
> @@ -853,15 +857,13 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
>   {
>   	unsigned long 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]))
> +	*offp = off % BPT_SIZE;

Can we use logical operation instead ?

	*offp = off & (BPT_SIZE - 1);

> +	if (*offp != 0 && *offp != 4)

Could be:
	if (off & 3)

>   		return NULL;
> -	*offp = off - offsetof(struct bpt, instr[0]);
> -	return (struct bpt *) (nip - off);
> +	return bpts + (off / BPT_SIZE);
>   }
>   
>   static struct bpt *new_breakpoint(unsigned long a)
> @@ -876,7 +878,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;
>   		}
>   	}
> diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
> new file mode 100644
> index 000000000000..ebb2dbc70ca8
> --- /dev/null
> +++ b/arch/powerpc/xmon/xmon_bpts.S
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <asm/ppc_asm.h>
> +#include <asm/asm-compat.h>
> +#include "xmon_bpts.h"
> +
> +.global bpt_table
> +bpt_table:
> +	.space NBPTS * 8

Should use BPT_SIZE instead of raw coding 8.

> diff --git a/arch/powerpc/xmon/xmon_bpts.h b/arch/powerpc/xmon/xmon_bpts.h
> new file mode 100644
> index 000000000000..840e70be7945
> --- /dev/null
> +++ b/arch/powerpc/xmon/xmon_bpts.h
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef XMON_BPTS_H
> +#define XMON_BPTS_H
> +
> +#define NBPTS	256
> +
> +#endif /* XMON_BPTS_H */
> +
> 

I think it would be better to split this patch in two patches:
1/ First patch to move breakpoints out of struct bpt into a bpt_table.
2/ Second patch to move bpt_table into .text section.

Christophe

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

* Re: [PATCH v5 00/21] Initial Prefixed Instruction support
  2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
                   ` (20 preceding siblings ...)
  2020-04-06  8:09 ` [PATCH v5 21/21] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
@ 2020-04-09  6:39 ` Christophe Leroy
  2020-04-09  7:28   ` Jordan Niethe
  21 siblings, 1 reply; 71+ messages in thread
From: Christophe Leroy @ 2020-04-09  6:39 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: bala24, alistair, dja, npiggin



On 04/06/2020 08:09 AM, Jordan Niethe wrote:
> 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.
> 
> v5 is based on feedback from Nick Piggins, Michael Ellerman, Balamuruhan
> Suriyakumar and Alistair Popple.
> The major changes:
>      - The ppc instruction type is now a struct
>      - Series now just based on next
>      - ppc_inst_masked() dropped
>      - Space for xmon breakpoints allocated in an assembly file
>      - "Add prefixed instructions to instruction data type" patch seperated in
>        to smaller patches
>      - Calling convention for create_branch() is changed
>      - Some places which had not been updated to use the data type are now updated

Build fails. I have not investigated why:

   CC      arch/powerpc/kernel/process.o
In file included from ./arch/powerpc/include/asm/code-patching.h:14:0,
                  from arch/powerpc/kernel/process.c:60:
./arch/powerpc/include/asm/inst.h:69:38: error: unknown type name ‘ppc_inst’
  static inline bool ppc_inst_prefixed(ppc_inst x)
                                       ^
./arch/powerpc/include/asm/inst.h:79:19: error: redefinition of 
‘ppc_inst_val’
  static inline u32 ppc_inst_val(struct ppc_inst x)
                    ^
./arch/powerpc/include/asm/inst.h:21:19: note: previous definition of 
‘ppc_inst_val’ was here
  static inline u32 ppc_inst_val(struct ppc_inst x)
                    ^
./arch/powerpc/include/asm/inst.h: In function ‘ppc_inst_len’:
./arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of 
function ‘ppc_inst_prefixed’ [-Werror=implicit-function-declaration]
   return (ppc_inst_prefixed(x)) ? 8  : 4;
           ^

Christophe

> 
> 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 (20):
>    powerpc/xmon: Remove store_inst() for patch_instruction()
>    powerpc/xmon: Move out-of-line instructions to text section
>    powerpc: Change calling convention for create_branch() et. al.
>    powerpc: Use a macro for creating instructions from u32s
>    powerpc: Use a function for getting the instruction op code
>    powerpc: Use an accessor for instructions
>    powerpc: Use a function for byte swapping instructions
>    powerpc: Introduce functions for instruction equality
>    powerpc: Use a datatype for instructions
>    powerpc: Use a function for reading instructions
>    powerpc: Define and use __get_user_instr{,inatomic}()
>    powerpc: Introduce a function for reporting instruction length
>    powerpc/xmon: Use a function for reading instructions
>    powerpc/xmon: Move insertion of breakpoint for xol'ing
>    powerpc: Make test_translate_branch() independent of instruction
>      length
>    powerpc: Define new SRR1 bits for a future ISA version
>    powerpc64: Add prefixed instructions to instruction data type
>    powerpc: Support prefixed instructions in alignment handler
>    powerpc sstep: Add support for prefixed load/stores
>    powerpc sstep: Add support for prefixed fixed-point arithmetic
> 
>   arch/powerpc/include/asm/code-patching.h |  37 +-
>   arch/powerpc/include/asm/inst.h          | 106 ++++++
>   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       |  28 ++
>   arch/powerpc/include/asm/uprobes.h       |   7 +-
>   arch/powerpc/kernel/align.c              |  13 +-
>   arch/powerpc/kernel/epapr_paravirt.c     |   5 +-
>   arch/powerpc/kernel/hw_breakpoint.c      |   5 +-
>   arch/powerpc/kernel/jump_label.c         |   5 +-
>   arch/powerpc/kernel/kgdb.c               |   9 +-
>   arch/powerpc/kernel/kprobes.c            |  24 +-
>   arch/powerpc/kernel/mce_power.c          |   5 +-
>   arch/powerpc/kernel/module_64.c          |   3 +-
>   arch/powerpc/kernel/optprobes.c          |  91 +++--
>   arch/powerpc/kernel/optprobes_head.S     |   3 +
>   arch/powerpc/kernel/security.c           |   9 +-
>   arch/powerpc/kernel/setup_32.c           |   4 +-
>   arch/powerpc/kernel/trace/ftrace.c       | 190 ++++++----
>   arch/powerpc/kernel/traps.c              |  20 +-
>   arch/powerpc/kernel/uprobes.c            |   3 +-
>   arch/powerpc/kernel/vecemu.c             |  20 +-
>   arch/powerpc/kvm/book3s_hv_nested.c      |   2 +-
>   arch/powerpc/kvm/book3s_hv_rm_mmu.c      |   2 +-
>   arch/powerpc/kvm/emulate_loadstore.c     |   2 +-
>   arch/powerpc/lib/code-patching.c         | 289 +++++++-------
>   arch/powerpc/lib/feature-fixups.c        |  69 ++--
>   arch/powerpc/lib/sstep.c                 | 455 ++++++++++++++++-------
>   arch/powerpc/lib/test_emulate_step.c     |  56 +--
>   arch/powerpc/perf/core-book3s.c          |   4 +-
>   arch/powerpc/xmon/Makefile               |   2 +-
>   arch/powerpc/xmon/xmon.c                 |  94 +++--
>   arch/powerpc/xmon/xmon_bpts.S            |  10 +
>   arch/powerpc/xmon/xmon_bpts.h            |   8 +
>   35 files changed, 1042 insertions(+), 562 deletions(-)
>   create mode 100644 arch/powerpc/include/asm/inst.h
>   create mode 100644 arch/powerpc/xmon/xmon_bpts.S
>   create mode 100644 arch/powerpc/xmon/xmon_bpts.h
> 

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

* Re: [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section
  2020-04-09  6:11   ` Christophe Leroy
@ 2020-04-09  7:26     ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-09  7:26 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Alistair Popple, Nicholas Piggin, Balamuruhan S, linuxppc-dev,
	Daniel Axtens

On Thu, Apr 9, 2020 at 4:11 PM Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
>
>
> Le 06/04/2020 à 10:09, Jordan Niethe a écrit :
> > 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
> > v5: - Do not use __section(), use a .space directive in .S file
>
> I was going to comment to use __section() instead of creating a
> dedicated .S file.
>
> Why did you change that in v5 ?
I noticed with some toolchains I was getting this message:
Warning: setting incorrect section attributes for .text.xmon_bpts
I was talking with mpe about it and he said that the usual way for
doing things like this was with .space in a .S file so I changed to
that way.
>
> >      - Simplify in_breakpoint_table() calculation
> >      - Define BPT_SIZE
> > ---
> >   arch/powerpc/xmon/Makefile    |  2 +-
> >   arch/powerpc/xmon/xmon.c      | 23 +++++++++++++----------
> >   arch/powerpc/xmon/xmon_bpts.S |  8 ++++++++
> >   arch/powerpc/xmon/xmon_bpts.h |  8 ++++++++
> >   4 files changed, 30 insertions(+), 11 deletions(-)
> >   create mode 100644 arch/powerpc/xmon/xmon_bpts.S
> >   create mode 100644 arch/powerpc/xmon/xmon_bpts.h
> >
> > diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
> > index c3842dbeb1b7..515a13ea6f28 100644
> > --- a/arch/powerpc/xmon/Makefile
> > +++ b/arch/powerpc/xmon/Makefile
> > @@ -21,7 +21,7 @@ endif
> >
> >   ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
> >
> > -obj-y                        += xmon.o nonstdio.o spr_access.o
> > +obj-y                        += xmon.o nonstdio.o spr_access.o xmon_bpts.o
> >
> >   ifdef CONFIG_XMON_DISASSEMBLY
> >   obj-y                       += ppc-dis.o ppc-opc.o
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index 02e3bd62cab4..049375206510 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -62,6 +62,7 @@
> >
> >   #include "nonstdio.h"
> >   #include "dis-asm.h"
> > +#include "xmon_bpts.h"
> >
> >   #ifdef CONFIG_SMP
> >   static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
> > @@ -97,7 +98,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;
> > @@ -108,7 +109,6 @@ struct bpt {
> >   #define BP_TRAP             2
> >   #define BP_DABR             4
> >
> > -#define NBPTS        256
> >   static struct bpt bpts[NBPTS];
> >   static struct bpt dabr;
> >   static struct bpt *iabr;
> > @@ -116,6 +116,10 @@ static unsigned bpinstr = 0x7fe00008;    /* trap */
> >
> >   #define BP_NUM(bp)  ((bp) - bpts + 1)
> >
> > +#define BPT_SIZE     (sizeof(unsigned int) * 2)
> > +#define BPT_WORDS    (BPT_SIZE / sizeof(unsigned int))
>
> Wouldn't it make more sense to do the following ? :
>
> #define BPT_WORDS       2
> #define BPT_SIZE        (BPT_WORDS * sizeof(unsigned int))
I defined it like that so when we changed unsigned int -> struct
ppc_inst it would be the correct size whether or not the struct
included a suffix.
Otherwise it would be more straightforward to do it like that.
>
> > +extern unsigned int bpt_table[NBPTS * BPT_WORDS];
>
> Should go in xmon_bpts.h if we keep the definition in xmon_bpts.S
Right.
>
> > +
> >   /* Prototypes */
> >   static int cmds(struct pt_regs *);
> >   static int mread(unsigned long, void *, int);
> > @@ -853,15 +857,13 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
> >   {
> >       unsigned long 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]))
> > +     *offp = off % BPT_SIZE;
>
> Can we use logical operation instead ?
Sure, I was just adapting how it was already but that would probably be clearer.
>
>         *offp = off & (BPT_SIZE - 1);
>
> > +     if (*offp != 0 && *offp != 4)
>
> Could be:
>         if (off & 3)
>
> >               return NULL;
> > -     *offp = off - offsetof(struct bpt, instr[0]);
> > -     return (struct bpt *) (nip - off);
> > +     return bpts + (off / BPT_SIZE);
> >   }
> >
> >   static struct bpt *new_breakpoint(unsigned long a)
> > @@ -876,7 +878,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;
> >               }
> >       }
> > diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
> > new file mode 100644
> > index 000000000000..ebb2dbc70ca8
> > --- /dev/null
> > +++ b/arch/powerpc/xmon/xmon_bpts.S
> > @@ -0,0 +1,8 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#include <asm/ppc_asm.h>
> > +#include <asm/asm-compat.h>
> > +#include "xmon_bpts.h"
> > +
> > +.global bpt_table
> > +bpt_table:
> > +     .space NBPTS * 8
>
> Should use BPT_SIZE instead of raw coding 8.
Right.
>
> > diff --git a/arch/powerpc/xmon/xmon_bpts.h b/arch/powerpc/xmon/xmon_bpts.h
> > new file mode 100644
> > index 000000000000..840e70be7945
> > --- /dev/null
> > +++ b/arch/powerpc/xmon/xmon_bpts.h
> > @@ -0,0 +1,8 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef XMON_BPTS_H
> > +#define XMON_BPTS_H
> > +
> > +#define NBPTS        256
> > +
> > +#endif /* XMON_BPTS_H */
> > +
> >
>
> I think it would be better to split this patch in two patches:
> 1/ First patch to move breakpoints out of struct bpt into a bpt_table.
> 2/ Second patch to move bpt_table into .text section.
Bala suggested so too, I will separate them next time.
>
> Christophe

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

* Re: [PATCH v5 00/21] Initial Prefixed Instruction support
  2020-04-09  6:39 ` [PATCH v5 00/21] Initial Prefixed Instruction support Christophe Leroy
@ 2020-04-09  7:28   ` Jordan Niethe
  0 siblings, 0 replies; 71+ messages in thread
From: Jordan Niethe @ 2020-04-09  7:28 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Alistair Popple, Nicholas Piggin, Balamuruhan S, linuxppc-dev,
	Daniel Axtens

On Thu, Apr 9, 2020 at 4:39 PM Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
>
>
> On 04/06/2020 08:09 AM, Jordan Niethe wrote:
> > 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.
> >
> > v5 is based on feedback from Nick Piggins, Michael Ellerman, Balamuruhan
> > Suriyakumar and Alistair Popple.
> > The major changes:
> >      - The ppc instruction type is now a struct
> >      - Series now just based on next
> >      - ppc_inst_masked() dropped
> >      - Space for xmon breakpoints allocated in an assembly file
> >      - "Add prefixed instructions to instruction data type" patch seperated in
> >        to smaller patches
> >      - Calling convention for create_branch() is changed
> >      - Some places which had not been updated to use the data type are now updated
>
> Build fails. I have not investigated why:
Thanks, I will check it out.
>
>    CC      arch/powerpc/kernel/process.o
> In file included from ./arch/powerpc/include/asm/code-patching.h:14:0,
>                   from arch/powerpc/kernel/process.c:60:
> ./arch/powerpc/include/asm/inst.h:69:38: error: unknown type name ‘ppc_inst’
>   static inline bool ppc_inst_prefixed(ppc_inst x)
>                                        ^
> ./arch/powerpc/include/asm/inst.h:79:19: error: redefinition of
> ‘ppc_inst_val’
>   static inline u32 ppc_inst_val(struct ppc_inst x)
>                     ^
> ./arch/powerpc/include/asm/inst.h:21:19: note: previous definition of
> ‘ppc_inst_val’ was here
>   static inline u32 ppc_inst_val(struct ppc_inst x)
>                     ^
> ./arch/powerpc/include/asm/inst.h: In function ‘ppc_inst_len’:
> ./arch/powerpc/include/asm/inst.h:103:10: error: implicit declaration of
> function ‘ppc_inst_prefixed’ [-Werror=implicit-function-declaration]
>    return (ppc_inst_prefixed(x)) ? 8  : 4;
>            ^
>
> Christophe
>
> >
> > 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 (20):
> >    powerpc/xmon: Remove store_inst() for patch_instruction()
> >    powerpc/xmon: Move out-of-line instructions to text section
> >    powerpc: Change calling convention for create_branch() et. al.
> >    powerpc: Use a macro for creating instructions from u32s
> >    powerpc: Use a function for getting the instruction op code
> >    powerpc: Use an accessor for instructions
> >    powerpc: Use a function for byte swapping instructions
> >    powerpc: Introduce functions for instruction equality
> >    powerpc: Use a datatype for instructions
> >    powerpc: Use a function for reading instructions
> >    powerpc: Define and use __get_user_instr{,inatomic}()
> >    powerpc: Introduce a function for reporting instruction length
> >    powerpc/xmon: Use a function for reading instructions
> >    powerpc/xmon: Move insertion of breakpoint for xol'ing
> >    powerpc: Make test_translate_branch() independent of instruction
> >      length
> >    powerpc: Define new SRR1 bits for a future ISA version
> >    powerpc64: Add prefixed instructions to instruction data type
> >    powerpc: Support prefixed instructions in alignment handler
> >    powerpc sstep: Add support for prefixed load/stores
> >    powerpc sstep: Add support for prefixed fixed-point arithmetic
> >
> >   arch/powerpc/include/asm/code-patching.h |  37 +-
> >   arch/powerpc/include/asm/inst.h          | 106 ++++++
> >   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       |  28 ++
> >   arch/powerpc/include/asm/uprobes.h       |   7 +-
> >   arch/powerpc/kernel/align.c              |  13 +-
> >   arch/powerpc/kernel/epapr_paravirt.c     |   5 +-
> >   arch/powerpc/kernel/hw_breakpoint.c      |   5 +-
> >   arch/powerpc/kernel/jump_label.c         |   5 +-
> >   arch/powerpc/kernel/kgdb.c               |   9 +-
> >   arch/powerpc/kernel/kprobes.c            |  24 +-
> >   arch/powerpc/kernel/mce_power.c          |   5 +-
> >   arch/powerpc/kernel/module_64.c          |   3 +-
> >   arch/powerpc/kernel/optprobes.c          |  91 +++--
> >   arch/powerpc/kernel/optprobes_head.S     |   3 +
> >   arch/powerpc/kernel/security.c           |   9 +-
> >   arch/powerpc/kernel/setup_32.c           |   4 +-
> >   arch/powerpc/kernel/trace/ftrace.c       | 190 ++++++----
> >   arch/powerpc/kernel/traps.c              |  20 +-
> >   arch/powerpc/kernel/uprobes.c            |   3 +-
> >   arch/powerpc/kernel/vecemu.c             |  20 +-
> >   arch/powerpc/kvm/book3s_hv_nested.c      |   2 +-
> >   arch/powerpc/kvm/book3s_hv_rm_mmu.c      |   2 +-
> >   arch/powerpc/kvm/emulate_loadstore.c     |   2 +-
> >   arch/powerpc/lib/code-patching.c         | 289 +++++++-------
> >   arch/powerpc/lib/feature-fixups.c        |  69 ++--
> >   arch/powerpc/lib/sstep.c                 | 455 ++++++++++++++++-------
> >   arch/powerpc/lib/test_emulate_step.c     |  56 +--
> >   arch/powerpc/perf/core-book3s.c          |   4 +-
> >   arch/powerpc/xmon/Makefile               |   2 +-
> >   arch/powerpc/xmon/xmon.c                 |  94 +++--
> >   arch/powerpc/xmon/xmon_bpts.S            |  10 +
> >   arch/powerpc/xmon/xmon_bpts.h            |   8 +
> >   35 files changed, 1042 insertions(+), 562 deletions(-)
> >   create mode 100644 arch/powerpc/include/asm/inst.h
> >   create mode 100644 arch/powerpc/xmon/xmon_bpts.S
> >   create mode 100644 arch/powerpc/xmon/xmon_bpts.h
> >

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-06  8:09 ` [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
  2020-04-06  9:52   ` Alistair Popple
  2020-04-06 11:04     ` kbuild test robot
@ 2020-04-13 12:04   ` Balamuruhan S
  2020-04-15  4:40     ` Jordan Niethe
  2 siblings, 1 reply; 71+ messages in thread
From: Balamuruhan S @ 2020-04-13 12:04 UTC (permalink / raw)
  To: Jordan Niethe, linuxppc-dev; +Cc: alistair, npiggin, dja

On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> 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
> v5:  - Distinguish normal instructions from prefixed instructions with a
>        0xff marker for the suffix.
>      - __patch_instruction() using std for prefixed instructions
> ---
>  arch/powerpc/include/asm/inst.h      | 71 ++++++++++++++++++++++++++--
>  arch/powerpc/include/asm/kprobes.h   |  2 +-
>  arch/powerpc/include/asm/uaccess.h   | 31 ++++++++++--
>  arch/powerpc/include/asm/uprobes.h   |  2 +-
>  arch/powerpc/kernel/optprobes.c      | 42 ++++++++--------
>  arch/powerpc/kernel/optprobes_head.S |  3 ++
>  arch/powerpc/kernel/trace/ftrace.c   | 26 +++++++++-
>  arch/powerpc/lib/code-patching.c     | 19 +++++---
>  arch/powerpc/lib/feature-fixups.c    |  5 +-
>  arch/powerpc/lib/sstep.c             |  4 +-
>  arch/powerpc/xmon/xmon.c             |  6 +--
>  arch/powerpc/xmon/xmon_bpts.S        |  4 +-
>  12 files changed, 171 insertions(+), 44 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> index 70b37a35a91a..7e23e7146c66 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -8,23 +8,67 @@
>  
>  struct ppc_inst {
>          u32 val;
> +#ifdef __powerpc64__
> +        u32 suffix;
> +#endif /* __powerpc64__ */
>  } __packed;
>  
> -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> +static inline int ppc_inst_opcode(struct ppc_inst x)
> +{
> +	return x.val >> 26;


why don't we wrap here and in `ppc_inst_opcode()` in patch 9 using
`ppc_inst_val()` ?


> +}
>  
>  static inline u32 ppc_inst_val(struct ppc_inst x)


There is another same definition below for the same function in
#else part of __powerpc64__ ifdef.


>  {
>  	return x.val;
>  }
>  
> -static inline bool ppc_inst_len(struct ppc_inst x)
> +#ifdef __powerpc64__
> +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> +
> +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y)
> })
> +
> +static inline u32 ppc_inst_suffix(struct ppc_inst x)
>  {
> -	return sizeof(struct ppc_inst);
> +	return x.suffix;
>  }
>  
> -static inline int ppc_inst_opcode(struct ppc_inst x)
> +static inline bool ppc_inst_prefixed(struct ppc_inst x) {
> +	return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) != 0xff;
> +}
> +
> +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
>  {
> -	return x.val >> 26;
> +	return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> +			       swab32(ppc_inst_suffix(x)));
> +}
> +
> +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> +{
> +	u32 val, suffix = 0xff;
> +	val = *(u32 *)ptr;
> +	if ((val >> 26) == 1)
> +		suffix = *((u32 *)ptr + 1);
> +	return ppc_inst_prefix(val, suffix);
> +}
> +
> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> +{
> +	if (ppc_inst_prefixed(x)) {
> +		*(u32 *)ptr = x.val;
> +		*((u32 *)ptr + 1) = x.suffix;
> +	} else {
> +		*(u32 *)ptr = x.val;


can we wrap here as well with `ppc_inst_val()` and `ppc_inst_suffix()` ?


> +	}
> +}
> +
> +#else
> +
> +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> +
> +static inline bool ppc_inst_prefixed(ppc_inst x)
> +{
> +	return 0;


Is it return !!0 or return false ?


>  }
>  
>  static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> ppc_inst x)
>  	return ppc_inst(swab32(ppc_inst_val(x)));
>  }
>  
> +static inline u32 ppc_inst_val(struct ppc_inst x)


[...] duplicate definition that is defined outside __powerpc64__ above.


> +{
> +	return x.val;
> +}
> +
>  static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
>  {
>  	return *ptr;
>  }
>  
> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> +{
> +	*ptr = x;
> +}
> +
> +#endif /* __powerpc64__ */
> +
>  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
>  {
>  	return !memcmp(&x, &y, sizeof(struct ppc_inst));
>  }
>  
> +static inline int ppc_inst_len(struct ppc_inst x)
> +{
> +	return (ppc_inst_prefixed(x)) ? 8  : 4;
> +}
> +
>  #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/uaccess.h
> b/arch/powerpc/include/asm/uaccess.h
> index c0a35e4586a5..5a3f486ddf02 100644
> --- a/arch/powerpc/include/asm/uaccess.h
> +++ b/arch/powerpc/include/asm/uaccess.h
> @@ -105,11 +105,34 @@ 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)))
>  
> -#define __get_user_instr(x, ptr) \
> -	__get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> +#define __get_user_instr(x, ptr)			\
> +({							\
> +	long __gui_ret = 0;				\
> +	unsigned int prefix, suffix;			\
> +	__gui_ret = __get_user(prefix, (unsigned int __user *)ptr);		
> \
> +	if (!__gui_ret && (prefix >> 26) == 1) {	\
> +		__gui_ret = __get_user(suffix, (unsigned int __user *)ptr + 1);
> 	\
> +		(x) = ppc_inst_prefix(prefix, suffix);	\
> +	} else {					\
> +		(x) = ppc_inst(prefix);			\
> +	}						\
> +	__gui_ret;					\
> +})
> +
> +#define __get_user_instr_inatomic(x, ptr)		\
> +({							\
> +	long __gui_ret = 0;				\
> +	unsigned int prefix, suffix;			\
> +	__gui_ret = __get_user_inatomic(prefix, (unsigned int __user *)ptr);	
> 	\
> +	if (!__gui_ret && (prefix >> 26) == 1) {	\
> +		__gui_ret = __get_user_inatomic(suffix, (unsigned int __user
> *)ptr + 1);	\
> +		(x) = ppc_inst_prefix(prefix, suffix);	\
> +	} else {					\
> +		(x) = ppc_inst(prefix);			\
> +	}						\
> +	__gui_ret;					\
> +})
>  
> -#define __get_user_instr_inatomic(x, ptr) \
> -	__get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
>  extern long __put_user_bad(void);
>  
>  /*
> diff --git a/arch/powerpc/include/asm/uprobes.h
> b/arch/powerpc/include/asm/uprobes.h
> index 7e3b329ba2d3..5bf65f5d44a9 100644
> --- a/arch/powerpc/include/asm/uprobes.h
> +++ b/arch/powerpc/include/asm/uprobes.h
> @@ -15,7 +15,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/optprobes.c
> b/arch/powerpc/kernel/optprobes.c
> index 684640b8fa2e..689daf430161 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -159,38 +159,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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> ___PPC_RT(3) |
> +	/* lis reg,(op)@highest */
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> ___PPC_RT(reg) |
>  			  ((val >> 48) & 0xffff)));
>  	addr++;
>  
> -	/* ori r3,r3,(op)@higher */
> -	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> ___PPC_RA(3) |
> -			  ___PPC_RS(3) | ((val >> 32) & 0xffff)));
> +	/* ori reg,reg,(op)@higher */
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
>  	addr++;
>  
> -	/* rldicr r3,r3,32,31 */
> -	patch_instruction((struct ppc_inst *)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((struct ppc_inst *)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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> ___PPC_RA(3) |
> -			  ___PPC_RS(3) | ((val >> 16) & 0xffff)));
> +	/* oris reg,reg,(op)@h */
> +	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> ___PPC_RA(reg) |
> +			  ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
>  	addr++;
>  
> -	/* ori r3,r3,(op)@l */
> -	patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> ___PPC_RA(3) |
> -			  ___PPC_RS(3) | (val & 0xffff)));
> +	/* ori reg,reg,(op)@l */
> +	patch_instruction((struct ppc_inst *)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)
>  {
> -	struct ppc_inst branch_op_callback, branch_emulate_step;
> +	struct 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;
> @@ -240,7 +240,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()
> @@ -271,7 +271,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(*p->ainsn.insn, buff + TMPL_INSN_IDX);
> +	temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> +	patch_imm64_load_insns(ppc_inst_val(temp) |
> +			       ((u64)ppc_inst_suffix(temp) << 32),


did we check building for ppc32 ?

I doubt we might hit build failure as `ppc_inst_suffix()` macro is not defined.


> +			       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 e78742613b36..16041a5c86d5 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -41,11 +41,35 @@
>  #define	NUM_FTRACE_TRAMPS	8
>  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
>  
> +#ifdef __powerpc64__
>  static long
>  probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
>  {
> -	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> +	u32 val, suffix = 0;


don't we need to initialize suffix with 0xff ?


> +	long err;
> +
> +	err = probe_kernel_read((void *)&val,
> +				src, sizeof(val));
> +	if (err)
> +		return err;
> +
> +	if ((val >> 26) == 1)
> +		err = probe_kernel_read((void *)&suffix,
> +					src + 4, MCOUNT_INSN_SIZE);
> +	if (err)
> +		return err;
> +
> +	*inst = ppc_inst_prefix(val, suffix);
> +
> +	return 0;
>  }
> +#else
> +static long
> +probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> +{
> +	return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE)
> +}
> +#endif
>  
>  static struct ppc_inst
>  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> patching.c
> index c329ad657302..b4007e03d8fa 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -24,12 +24,19 @@ static int __patch_instruction(struct ppc_inst
> *exec_addr, struct ppc_inst instr
>  {
>  	int err = 0;
>  
> -	__put_user_asm(ppc_inst_val(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)) {
> +		__put_user_asm(ppc_inst_val(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));
> +	} else {
> +		__put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
> ppc_inst_val(instr), patch_addr, err, "std");
> +		if (err)
> +			return err;
> +		asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r"
> (patch_addr),
> +								    "r"
> (exec_addr));
> +	}


can we keep these 2 lines out of conditions as it remains to be the same ?

if (err)
	return err;
asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr), "r"
(exec_addr));


>  
>  	return 0;
>  }
> diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> fixups.c
> index f00dd13b1c3c..5519cec83cc8 100644
> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -84,12 +84,13 @@ static int patch_feature_section(unsigned long value,
> struct fixup_entry *fcur)
>  	src = alt_start;
>  	dest = start;
>  
> -	for (; src < alt_end; src++, dest++) {
> +	for (; src < alt_end; src = (void *)src +
> ppc_inst_len(ppc_inst_read(src)),
> +	     (dest = (void *)dest + ppc_inst_len(ppc_inst_read(dest)))) {
>  		if (patch_alt_instruction(src, dest, alt_start, alt_end))
>  			return 1;
>  	}
>  
> -	for (; dest < end; dest++)
> +	for (; dest < end; dest = (void *)dest +
> ppc_inst_len(ppc_inst(PPC_INST_NOP)))
>  		raw_patch_instruction(dest, ppc_inst(PPC_INST_NOP));
>  
>  	return 0;
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 52ddd3122dc8..8b285bf11218 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_val(instr);
> +	suffix = ppc_inst_suffix(instr);


same here, I doubt it might break for ppc32.


-- Bala
> +
>  	op->type = COMPUTE;
>  
>  	opcode = word >> 26;
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 6f3bcdcfc9c7..b704aebb099a 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -761,8 +761,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;
>  	}
> @@ -863,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip,
> unsigned long *offp)
>  	if (off >= sizeof(bpt_table))
>  		return NULL;
>  	*offp = off % BPT_SIZE;
> -	if (*offp != 0 && *offp != 4)
> +	if (*offp != 0 && *offp != 4 && *offp != 8)
>  		return NULL;
>  	return bpts + (off / BPT_SIZE);
>  }
> diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
> index ebb2dbc70ca8..09058eb6abbd 100644
> --- a/arch/powerpc/xmon/xmon_bpts.S
> +++ b/arch/powerpc/xmon/xmon_bpts.S
> @@ -3,6 +3,8 @@
>  #include <asm/asm-compat.h>
>  #include "xmon_bpts.h"
>  
> +/* Prefixed instructions can not cross 64 byte boundaries */
> +.align 6
>  .global bpt_table
>  bpt_table:
> -	.space NBPTS * 8
> +	.space NBPTS * 16


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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-13 12:04   ` Balamuruhan S
@ 2020-04-15  4:40     ` Jordan Niethe
  2020-04-15  8:14       ` Balamuruhan S
  0 siblings, 1 reply; 71+ messages in thread
From: Jordan Niethe @ 2020-04-15  4:40 UTC (permalink / raw)
  To: Balamuruhan S
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Mon, Apr 13, 2020 at 10:04 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
>
> On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > 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
> > v5:  - Distinguish normal instructions from prefixed instructions with a
> >        0xff marker for the suffix.
> >      - __patch_instruction() using std for prefixed instructions
> > ---
> >  arch/powerpc/include/asm/inst.h      | 71 ++++++++++++++++++++++++++--
> >  arch/powerpc/include/asm/kprobes.h   |  2 +-
> >  arch/powerpc/include/asm/uaccess.h   | 31 ++++++++++--
> >  arch/powerpc/include/asm/uprobes.h   |  2 +-
> >  arch/powerpc/kernel/optprobes.c      | 42 ++++++++--------
> >  arch/powerpc/kernel/optprobes_head.S |  3 ++
> >  arch/powerpc/kernel/trace/ftrace.c   | 26 +++++++++-
> >  arch/powerpc/lib/code-patching.c     | 19 +++++---
> >  arch/powerpc/lib/feature-fixups.c    |  5 +-
> >  arch/powerpc/lib/sstep.c             |  4 +-
> >  arch/powerpc/xmon/xmon.c             |  6 +--
> >  arch/powerpc/xmon/xmon_bpts.S        |  4 +-
> >  12 files changed, 171 insertions(+), 44 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/inst.h
> > b/arch/powerpc/include/asm/inst.h
> > index 70b37a35a91a..7e23e7146c66 100644
> > --- a/arch/powerpc/include/asm/inst.h
> > +++ b/arch/powerpc/include/asm/inst.h
> > @@ -8,23 +8,67 @@
> >
> >  struct ppc_inst {
> >          u32 val;
> > +#ifdef __powerpc64__
> > +        u32 suffix;
> > +#endif /* __powerpc64__ */
> >  } __packed;
> >
> > -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > +static inline int ppc_inst_opcode(struct ppc_inst x)
> > +{
> > +     return x.val >> 26;
>
>
> why don't we wrap here and in `ppc_inst_opcode()` in patch 9 using
> `ppc_inst_val()` ?
Will do.
>
>
> > +}
> >
> >  static inline u32 ppc_inst_val(struct ppc_inst x)
>
>
> There is another same definition below for the same function in
> #else part of __powerpc64__ ifdef.
Thanks
>
>
> >  {
> >       return x.val;
> >  }
> >
> > -static inline bool ppc_inst_len(struct ppc_inst x)
> > +#ifdef __powerpc64__
> > +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> > +
> > +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y)
> > })
> > +
> > +static inline u32 ppc_inst_suffix(struct ppc_inst x)
> >  {
> > -     return sizeof(struct ppc_inst);
> > +     return x.suffix;
> >  }
> >
> > -static inline int ppc_inst_opcode(struct ppc_inst x)
> > +static inline bool ppc_inst_prefixed(struct ppc_inst x) {
> > +     return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) != 0xff;
> > +}
> > +
> > +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> >  {
> > -     return x.val >> 26;
> > +     return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> > +                            swab32(ppc_inst_suffix(x)));
> > +}
> > +
> > +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > +{
> > +     u32 val, suffix = 0xff;
> > +     val = *(u32 *)ptr;
> > +     if ((val >> 26) == 1)
> > +             suffix = *((u32 *)ptr + 1);
> > +     return ppc_inst_prefix(val, suffix);
> > +}
> > +
> > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> > +{
> > +     if (ppc_inst_prefixed(x)) {
> > +             *(u32 *)ptr = x.val;
> > +             *((u32 *)ptr + 1) = x.suffix;
> > +     } else {
> > +             *(u32 *)ptr = x.val;
>
>
> can we wrap here as well with `ppc_inst_val()` and `ppc_inst_suffix()` ?
Yeah no reason not too.
>
>
> > +     }
> > +}
> > +
> > +#else
> > +
> > +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > +
> > +static inline bool ppc_inst_prefixed(ppc_inst x)
> > +{
> > +     return 0;
>
>
> Is it return !!0 or return false ?
False probably will make more sense.
>
>
> >  }
> >
> >  static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> > @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> > ppc_inst x)
> >       return ppc_inst(swab32(ppc_inst_val(x)));
> >  }
> >
> > +static inline u32 ppc_inst_val(struct ppc_inst x)
>
>
> [...] duplicate definition that is defined outside __powerpc64__ above.
>
>
> > +{
> > +     return x.val;
> > +}
> > +
> >  static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> >  {
> >       return *ptr;
> >  }
> >
> > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> > +{
> > +     *ptr = x;
> > +}
> > +
> > +#endif /* __powerpc64__ */
> > +
> >  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
> >  {
> >       return !memcmp(&x, &y, sizeof(struct ppc_inst));
> >  }
> >
> > +static inline int ppc_inst_len(struct ppc_inst x)
> > +{
> > +     return (ppc_inst_prefixed(x)) ? 8  : 4;
> > +}
> > +
> >  #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/uaccess.h
> > b/arch/powerpc/include/asm/uaccess.h
> > index c0a35e4586a5..5a3f486ddf02 100644
> > --- a/arch/powerpc/include/asm/uaccess.h
> > +++ b/arch/powerpc/include/asm/uaccess.h
> > @@ -105,11 +105,34 @@ 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)))
> >
> > -#define __get_user_instr(x, ptr) \
> > -     __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> > +#define __get_user_instr(x, ptr)                     \
> > +({                                                   \
> > +     long __gui_ret = 0;                             \
> > +     unsigned int prefix, suffix;                    \
> > +     __gui_ret = __get_user(prefix, (unsigned int __user *)ptr);
> > \
> > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > +             __gui_ret = __get_user(suffix, (unsigned int __user *)ptr + 1);
> >       \
> > +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > +     } else {                                        \
> > +             (x) = ppc_inst(prefix);                 \
> > +     }                                               \
> > +     __gui_ret;                                      \
> > +})
> > +
> > +#define __get_user_instr_inatomic(x, ptr)            \
> > +({                                                   \
> > +     long __gui_ret = 0;                             \
> > +     unsigned int prefix, suffix;                    \
> > +     __gui_ret = __get_user_inatomic(prefix, (unsigned int __user *)ptr);
> >       \
> > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > +             __gui_ret = __get_user_inatomic(suffix, (unsigned int __user
> > *)ptr + 1);   \
> > +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > +     } else {                                        \
> > +             (x) = ppc_inst(prefix);                 \
> > +     }                                               \
> > +     __gui_ret;                                      \
> > +})
> >
> > -#define __get_user_instr_inatomic(x, ptr) \
> > -     __get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
> >  extern long __put_user_bad(void);
> >
> >  /*
> > diff --git a/arch/powerpc/include/asm/uprobes.h
> > b/arch/powerpc/include/asm/uprobes.h
> > index 7e3b329ba2d3..5bf65f5d44a9 100644
> > --- a/arch/powerpc/include/asm/uprobes.h
> > +++ b/arch/powerpc/include/asm/uprobes.h
> > @@ -15,7 +15,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/optprobes.c
> > b/arch/powerpc/kernel/optprobes.c
> > index 684640b8fa2e..689daf430161 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -159,38 +159,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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> > ___PPC_RT(3) |
> > +     /* lis reg,(op)@highest */
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS |
> > ___PPC_RT(reg) |
> >                         ((val >> 48) & 0xffff)));
> >       addr++;
> >
> > -     /* ori r3,r3,(op)@higher */
> > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > ___PPC_RA(3) |
> > -                       ___PPC_RS(3) | ((val >> 32) & 0xffff)));
> > +     /* ori reg,reg,(op)@higher */
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > ___PPC_RA(reg) |
> > +                       ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
> >       addr++;
> >
> > -     /* rldicr r3,r3,32,31 */
> > -     patch_instruction((struct ppc_inst *)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((struct ppc_inst *)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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> > ___PPC_RA(3) |
> > -                       ___PPC_RS(3) | ((val >> 16) & 0xffff)));
> > +     /* oris reg,reg,(op)@h */
> > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> > ___PPC_RA(reg) |
> > +                       ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
> >       addr++;
> >
> > -     /* ori r3,r3,(op)@l */
> > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > ___PPC_RA(3) |
> > -                       ___PPC_RS(3) | (val & 0xffff)));
> > +     /* ori reg,reg,(op)@l */
> > +     patch_instruction((struct ppc_inst *)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)
> >  {
> > -     struct ppc_inst branch_op_callback, branch_emulate_step;
> > +     struct 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;
> > @@ -240,7 +240,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()
> > @@ -271,7 +271,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(*p->ainsn.insn, buff + TMPL_INSN_IDX);
> > +     temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> > +     patch_imm64_load_insns(ppc_inst_val(temp) |
> > +                            ((u64)ppc_inst_suffix(temp) << 32),
>
>
> did we check building for ppc32 ?
Yeah I need to do so.
>
> I doubt we might hit build failure as `ppc_inst_suffix()` macro is not defined.
>
>
> > +                            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 e78742613b36..16041a5c86d5 100644
> > --- a/arch/powerpc/kernel/trace/ftrace.c
> > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > @@ -41,11 +41,35 @@
> >  #define      NUM_FTRACE_TRAMPS       8
> >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> >
> > +#ifdef __powerpc64__
> >  static long
> >  probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> >  {
> > -     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> > +     u32 val, suffix = 0;
>
>
> don't we need to initialize suffix with 0xff ?
Good catch, that was causing problems.
>
>
> > +     long err;
> > +
> > +     err = probe_kernel_read((void *)&val,
> > +                             src, sizeof(val));
> > +     if (err)
> > +             return err;
> > +
> > +     if ((val >> 26) == 1)
> > +             err = probe_kernel_read((void *)&suffix,
> > +                                     src + 4, MCOUNT_INSN_SIZE);
> > +     if (err)
> > +             return err;
> > +
> > +     *inst = ppc_inst_prefix(val, suffix);
> > +
> > +     return 0;
> >  }
> > +#else
> > +static long
> > +probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> > +{
> > +     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE)
> > +}
> > +#endif
> >
> >  static struct ppc_inst
> >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > patching.c
> > index c329ad657302..b4007e03d8fa 100644
> > --- a/arch/powerpc/lib/code-patching.c
> > +++ b/arch/powerpc/lib/code-patching.c
> > @@ -24,12 +24,19 @@ static int __patch_instruction(struct ppc_inst
> > *exec_addr, struct ppc_inst instr
> >  {
> >       int err = 0;
> >
> > -     __put_user_asm(ppc_inst_val(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)) {
> > +             __put_user_asm(ppc_inst_val(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));
> > +     } else {
> > +             __put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
> > ppc_inst_val(instr), patch_addr, err, "std");
> > +             if (err)
> > +                     return err;
> > +             asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r"
> > (patch_addr),
> > +                                                                 "r"
> > (exec_addr));
> > +     }
>
>
> can we keep these 2 lines out of conditions as it remains to be the same ?
True.
>
> if (err)
>         return err;
> asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr), "r"
> (exec_addr));
>
>
> >
> >       return 0;
> >  }
> > diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-
> > fixups.c
> > index f00dd13b1c3c..5519cec83cc8 100644
> > --- a/arch/powerpc/lib/feature-fixups.c
> > +++ b/arch/powerpc/lib/feature-fixups.c
> > @@ -84,12 +84,13 @@ static int patch_feature_section(unsigned long value,
> > struct fixup_entry *fcur)
> >       src = alt_start;
> >       dest = start;
> >
> > -     for (; src < alt_end; src++, dest++) {
> > +     for (; src < alt_end; src = (void *)src +
> > ppc_inst_len(ppc_inst_read(src)),
> > +          (dest = (void *)dest + ppc_inst_len(ppc_inst_read(dest)))) {
> >               if (patch_alt_instruction(src, dest, alt_start, alt_end))
> >                       return 1;
> >       }
> >
> > -     for (; dest < end; dest++)
> > +     for (; dest < end; dest = (void *)dest +
> > ppc_inst_len(ppc_inst(PPC_INST_NOP)))
> >               raw_patch_instruction(dest, ppc_inst(PPC_INST_NOP));
> >
> >       return 0;
> > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > index 52ddd3122dc8..8b285bf11218 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_val(instr);
> > +     suffix = ppc_inst_suffix(instr);
>
>
> same here, I doubt it might break for ppc32.
Yeah I need to work on ppc32.
>
>
> -- Bala
> > +
> >       op->type = COMPUTE;
> >
> >       opcode = word >> 26;
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index 6f3bcdcfc9c7..b704aebb099a 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -761,8 +761,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;
> >       }
> > @@ -863,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip,
> > unsigned long *offp)
> >       if (off >= sizeof(bpt_table))
> >               return NULL;
> >       *offp = off % BPT_SIZE;
> > -     if (*offp != 0 && *offp != 4)
> > +     if (*offp != 0 && *offp != 4 && *offp != 8)
> >               return NULL;
> >       return bpts + (off / BPT_SIZE);
> >  }
> > diff --git a/arch/powerpc/xmon/xmon_bpts.S b/arch/powerpc/xmon/xmon_bpts.S
> > index ebb2dbc70ca8..09058eb6abbd 100644
> > --- a/arch/powerpc/xmon/xmon_bpts.S
> > +++ b/arch/powerpc/xmon/xmon_bpts.S
> > @@ -3,6 +3,8 @@
> >  #include <asm/asm-compat.h>
> >  #include "xmon_bpts.h"
> >
> > +/* Prefixed instructions can not cross 64 byte boundaries */
> > +.align 6
> >  .global bpt_table
> >  bpt_table:
> > -     .space NBPTS * 8
> > +     .space NBPTS * 16
>

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

* Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type
  2020-04-15  4:40     ` Jordan Niethe
@ 2020-04-15  8:14       ` Balamuruhan S
  0 siblings, 0 replies; 71+ messages in thread
From: Balamuruhan S @ 2020-04-15  8:14 UTC (permalink / raw)
  To: Jordan Niethe
  Cc: Alistair Popple, linuxppc-dev, Nicholas Piggin, Daniel Axtens

On Wed, 2020-04-15 at 14:40 +1000, Jordan Niethe wrote:
> On Mon, Apr 13, 2020 at 10:04 PM Balamuruhan S <bala24@linux.ibm.com> wrote:
> > On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> > > 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
> > > v5:  - Distinguish normal instructions from prefixed instructions with a
> > >        0xff marker for the suffix.
> > >      - __patch_instruction() using std for prefixed instructions
> > > ---
> > >  arch/powerpc/include/asm/inst.h      | 71 ++++++++++++++++++++++++++--
> > >  arch/powerpc/include/asm/kprobes.h   |  2 +-
> > >  arch/powerpc/include/asm/uaccess.h   | 31 ++++++++++--
> > >  arch/powerpc/include/asm/uprobes.h   |  2 +-
> > >  arch/powerpc/kernel/optprobes.c      | 42 ++++++++--------
> > >  arch/powerpc/kernel/optprobes_head.S |  3 ++
> > >  arch/powerpc/kernel/trace/ftrace.c   | 26 +++++++++-
> > >  arch/powerpc/lib/code-patching.c     | 19 +++++---
> > >  arch/powerpc/lib/feature-fixups.c    |  5 +-
> > >  arch/powerpc/lib/sstep.c             |  4 +-
> > >  arch/powerpc/xmon/xmon.c             |  6 +--
> > >  arch/powerpc/xmon/xmon_bpts.S        |  4 +-
> > >  12 files changed, 171 insertions(+), 44 deletions(-)
> > > 
> > > diff --git a/arch/powerpc/include/asm/inst.h
> > > b/arch/powerpc/include/asm/inst.h
> > > index 70b37a35a91a..7e23e7146c66 100644
> > > --- a/arch/powerpc/include/asm/inst.h
> > > +++ b/arch/powerpc/include/asm/inst.h
> > > @@ -8,23 +8,67 @@
> > > 
> > >  struct ppc_inst {
> > >          u32 val;
> > > +#ifdef __powerpc64__
> > > +        u32 suffix;
> > > +#endif /* __powerpc64__ */
> > >  } __packed;
> > > 
> > > -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > > +static inline int ppc_inst_opcode(struct ppc_inst x)
> > > +{
> > > +     return x.val >> 26;
> > 
> > why don't we wrap here and in `ppc_inst_opcode()` in patch 9 using
> > `ppc_inst_val()` ?
> Will do.
> > 
> > > +}
> > > 
> > >  static inline u32 ppc_inst_val(struct ppc_inst x)
> > 
> > There is another same definition below for the same function in
> > #else part of __powerpc64__ ifdef.
> Thanks
> > 
> > >  {
> > >       return x.val;
> > >  }
> > > 
> > > -static inline bool ppc_inst_len(struct ppc_inst x)
> > > +#ifdef __powerpc64__
> > > +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> > > +
> > > +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix =
> > > (y)
> > > })
> > > +
> > > +static inline u32 ppc_inst_suffix(struct ppc_inst x)
> > >  {
> > > -     return sizeof(struct ppc_inst);
> > > +     return x.suffix;
> > >  }
> > > 
> > > -static inline int ppc_inst_opcode(struct ppc_inst x)
> > > +static inline bool ppc_inst_prefixed(struct ppc_inst x) {
> > > +     return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) !=
> > > 0xff;
> > > +}
> > > +
> > > +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> > >  {
> > > -     return x.val >> 26;
> > > +     return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> > > +                            swab32(ppc_inst_suffix(x)));
> > > +}
> > > +
> > > +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > > +{
> > > +     u32 val, suffix = 0xff;
> > > +     val = *(u32 *)ptr;
> > > +     if ((val >> 26) == 1)
> > > +             suffix = *((u32 *)ptr + 1);
> > > +     return ppc_inst_prefix(val, suffix);
> > > +}
> > > +
> > > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst
> > > x)
> > > +{
> > > +     if (ppc_inst_prefixed(x)) {
> > > +             *(u32 *)ptr = x.val;
> > > +             *((u32 *)ptr + 1) = x.suffix;
> > > +     } else {
> > > +             *(u32 *)ptr = x.val;
> > 
> > can we wrap here as well with `ppc_inst_val()` and `ppc_inst_suffix()` ?
> Yeah no reason not too.
> > 
> > > +     }
> > > +}
> > > +
> > > +#else
> > > +
> > > +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> > > +
> > > +static inline bool ppc_inst_prefixed(ppc_inst x)
> > > +{
> > > +     return 0;
> > 
> > Is it return !!0 or return false ?
> False probably will make more sense.
> > 
> > >  }
> > > 
> > >  static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> > > @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> > > ppc_inst x)
> > >       return ppc_inst(swab32(ppc_inst_val(x)));
> > >  }
> > > 
> > > +static inline u32 ppc_inst_val(struct ppc_inst x)
> > 
> > [...] duplicate definition that is defined outside __powerpc64__ above.
> > 
> > 
> > > +{
> > > +     return x.val;
> > > +}
> > > +
> > >  static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> > >  {
> > >       return *ptr;
> > >  }
> > > 
> > > +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst
> > > x)
> > > +{
> > > +     *ptr = x;
> > > +}
> > > +
> > > +#endif /* __powerpc64__ */
> > > +
> > >  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
> > >  {
> > >       return !memcmp(&x, &y, sizeof(struct ppc_inst));
> > >  }
> > > 
> > > +static inline int ppc_inst_len(struct ppc_inst x)
> > > +{
> > > +     return (ppc_inst_prefixed(x)) ? 8  : 4;
> > > +}
> > > +
> > >  #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/uaccess.h
> > > b/arch/powerpc/include/asm/uaccess.h
> > > index c0a35e4586a5..5a3f486ddf02 100644
> > > --- a/arch/powerpc/include/asm/uaccess.h
> > > +++ b/arch/powerpc/include/asm/uaccess.h
> > > @@ -105,11 +105,34 @@ 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)))
> > > 
> > > -#define __get_user_instr(x, ptr) \
> > > -     __get_user_nocheck((x).val, (u32 *)(ptr), sizeof(u32), true)
> > > +#define __get_user_instr(x, ptr)                     \
> > > +({                                                   \
> > > +     long __gui_ret = 0;                             \
> > > +     unsigned int prefix, suffix;                    \
> > > +     __gui_ret = __get_user(prefix, (unsigned int __user *)ptr);
> > > \
> > > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > > +             __gui_ret = __get_user(suffix, (unsigned int __user *)ptr +
> > > 1);
> > >       \
> > > +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > > +     } else {                                        \
> > > +             (x) = ppc_inst(prefix);                 \
> > > +     }                                               \
> > > +     __gui_ret;                                      \
> > > +})
> > > +
> > > +#define __get_user_instr_inatomic(x, ptr)            \
> > > +({                                                   \
> > > +     long __gui_ret = 0;                             \
> > > +     unsigned int prefix, suffix;                    \
> > > +     __gui_ret = __get_user_inatomic(prefix, (unsigned int __user
> > > *)ptr);
> > >       \
> > > +     if (!__gui_ret && (prefix >> 26) == 1) {        \
> > > +             __gui_ret = __get_user_inatomic(suffix, (unsigned int
> > > __user
> > > *)ptr + 1);   \
> > > +             (x) = ppc_inst_prefix(prefix, suffix);  \
> > > +     } else {                                        \
> > > +             (x) = ppc_inst(prefix);                 \
> > > +     }                                               \
> > > +     __gui_ret;                                      \
> > > +})
> > > 
> > > -#define __get_user_instr_inatomic(x, ptr) \
> > > -     __get_user_nosleep((x).val, (u32 *)(ptr), sizeof(u32))
> > >  extern long __put_user_bad(void);
> > > 
> > >  /*
> > > diff --git a/arch/powerpc/include/asm/uprobes.h
> > > b/arch/powerpc/include/asm/uprobes.h
> > > index 7e3b329ba2d3..5bf65f5d44a9 100644
> > > --- a/arch/powerpc/include/asm/uprobes.h
> > > +++ b/arch/powerpc/include/asm/uprobes.h
> > > @@ -15,7 +15,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/optprobes.c
> > > b/arch/powerpc/kernel/optprobes.c
> > > index 684640b8fa2e..689daf430161 100644
> > > --- a/arch/powerpc/kernel/optprobes.c
> > > +++ b/arch/powerpc/kernel/optprobes.c
> > > @@ -159,38 +159,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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS
> > > |
> > > ___PPC_RT(3) |
> > > +     /* lis reg,(op)@highest */
> > > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ADDIS
> > > |
> > > ___PPC_RT(reg) |
> > >                         ((val >> 48) & 0xffff)));
> > >       addr++;
> > > 
> > > -     /* ori r3,r3,(op)@higher */
> > > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > > ___PPC_RA(3) |
> > > -                       ___PPC_RS(3) | ((val >> 32) & 0xffff)));
> > > +     /* ori reg,reg,(op)@higher */
> > > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > > ___PPC_RA(reg) |
> > > +                       ___PPC_RS(reg) | ((val >> 32) & 0xffff)));
> > >       addr++;
> > > 
> > > -     /* rldicr r3,r3,32,31 */
> > > -     patch_instruction((struct ppc_inst *)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((struct ppc_inst *)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((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> > > ___PPC_RA(3) |
> > > -                       ___PPC_RS(3) | ((val >> 16) & 0xffff)));
> > > +     /* oris reg,reg,(op)@h */
> > > +     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORIS |
> > > ___PPC_RA(reg) |
> > > +                       ___PPC_RS(reg) | ((val >> 16) & 0xffff)));
> > >       addr++;
> > > 
> > > -     /* ori r3,r3,(op)@l */
> > > -     patch_instruction((struct ppc_inst *)addr, ppc_inst(PPC_INST_ORI |
> > > ___PPC_RA(3) |
> > > -                       ___PPC_RS(3) | (val & 0xffff)));
> > > +     /* ori reg,reg,(op)@l */
> > > +     patch_instruction((struct ppc_inst *)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)
> > >  {
> > > -     struct ppc_inst branch_op_callback, branch_emulate_step;
> > > +     struct 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;
> > > @@ -240,7 +240,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()
> > > @@ -271,7 +271,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(*p->ainsn.insn, buff + TMPL_INSN_IDX);
> > > +     temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
> > > +     patch_imm64_load_insns(ppc_inst_val(temp) |
> > > +                            ((u64)ppc_inst_suffix(temp) << 32),
> > 
> > did we check building for ppc32 ?
> Yeah I need to do so.
> > I doubt we might hit build failure as `ppc_inst_suffix()` macro is not
> > defined.
> > 
> > 
> > > +                            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 e78742613b36..16041a5c86d5 100644
> > > --- a/arch/powerpc/kernel/trace/ftrace.c
> > > +++ b/arch/powerpc/kernel/trace/ftrace.c
> > > @@ -41,11 +41,35 @@
> > >  #define      NUM_FTRACE_TRAMPS       8
> > >  static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
> > > 
> > > +#ifdef __powerpc64__
> > >  static long
> > >  probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> > >  {
> > > -     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE);
> > > +     u32 val, suffix = 0;
> > 
> > don't we need to initialize suffix with 0xff ?
> Good catch, that was causing problems.


Also we can do,

if ((val >> 26) == 1)
{
	err = probe_kernel_read((void *)&suffix,
                                src + 4, MCOUNT_INSN_SIZE);
	if (err)
        	return err;
	*inst = ppc_inst_prefix(val, suffix);
}
else
	*inst = ppc_inst(val);

to explicitly show a non-prefixed instruction and we do not have to
initialize suffix to 0xff, as ppc_inst() would take care.

-- Bala

> > 
> > > +     long err;
> > > +
> > > +     err = probe_kernel_read((void *)&val,
> > > +                             src, sizeof(val));
> > > +     if (err)
> > > +             return err;
> > > +
> > > +     if ((val >> 26) == 1)
> > > +             err = probe_kernel_read((void *)&suffix,
> > > +                                     src + 4, MCOUNT_INSN_SIZE);
> > > +     if (err)
> > > +             return err;
> > > +
> > > +     *inst = ppc_inst_prefix(val, suffix);
> > > +
> > > +     return 0;
> > >  }
> > > +#else
> > > +static long
> > > +probe_kernel_read_inst(struct ppc_inst *inst, const void *src)
> > > +{
> > > +     return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE)
> > > +}
> > > +#endif
> > > 
> > >  static struct ppc_inst
> > >  ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
> > > diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-
> > > patching.c
> > > index c329ad657302..b4007e03d8fa 100644
> > > --- a/arch/powerpc/lib/code-patching.c
> > > +++ b/arch/powerpc/lib/code-patching.c
> > > @@ -24,12 +24,19 @@ static int __patch_instruction(struct ppc_inst
> > > *exec_addr, struct ppc_inst instr
> > >  {
> > >       int err = 0;
> > > 
> > > -     __put_user_asm(ppc_inst_val(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)) {
> > > +             __put_user_asm(ppc_inst_val(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));
> > > +     } else {
> > > +             __put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
> > > ppc_inst_val(instr), patch_addr, err, "std");
> > > +             if (err)
> > > +                     return err;
> > > +             asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r"
> > > (patch_addr),
> > > +                                                                 "r"
> > > (exec_addr));
> > > +     }
> > 
> > can we keep these 2 lines out of conditions as it remains to be the same ?
> True.
> > if (err)
> >         return err;
> > asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr), "r"
> > (exec_addr));
> > 
> > 
> > >       return 0;
> > >  }
> > > diff --git a/arch/powerpc/lib/feature-fixups.c
> > > b/arch/powerpc/lib/feature-
> > > fixups.c
> > > index f00dd13b1c3c..5519cec83cc8 100644
> > > --- a/arch/powerpc/lib/feature-fixups.c
> > > +++ b/arch/powerpc/lib/feature-fixups.c
> > > @@ -84,12 +84,13 @@ static int patch_feature_section(unsigned long value,
> > > struct fixup_entry *fcur)
> > >       src = alt_start;
> > >       dest = start;
> > > 
> > > -     for (; src < alt_end; src++, dest++) {
> > > +     for (; src < alt_end; src = (void *)src +
> > > ppc_inst_len(ppc_inst_read(src)),
> > > +          (dest = (void *)dest + ppc_inst_len(ppc_inst_read(dest)))) {
> > >               if (patch_alt_instruction(src, dest, alt_start, alt_end))
> > >                       return 1;
> > >       }
> > > 
> > > -     for (; dest < end; dest++)
> > > +     for (; dest < end; dest = (void *)dest +
> > > ppc_inst_len(ppc_inst(PPC_INST_NOP)))
> > >               raw_patch_instruction(dest, ppc_inst(PPC_INST_NOP));
> > > 
> > >       return 0;
> > > diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> > > index 52ddd3122dc8..8b285bf11218 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_val(instr);
> > > +     suffix = ppc_inst_suffix(instr);
> > 
> > same here, I doubt it might break for ppc32.
> Yeah I need to work on ppc32.
> > 
> > -- Bala
> > > +
> > >       op->type = COMPUTE;
> > > 
> > >       opcode = word >> 26;
> > > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > > index 6f3bcdcfc9c7..b704aebb099a 100644
> > > --- a/arch/powerpc/xmon/xmon.c
> > > +++ b/arch/powerpc/xmon/xmon.c
> > > @@ -761,8 +761,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;
> > >       }
> > > @@ -863,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long
> > > nip,
> > > unsigned long *offp)
> > >       if (off >= sizeof(bpt_table))
> > >               return NULL;
> > >       *offp = off % BPT_SIZE;
> > > -     if (*offp != 0 && *offp != 4)
> > > +     if (*offp != 0 && *offp != 4 && *offp != 8)
> > >               return NULL;
> > >       return bpts + (off / BPT_SIZE);
> > >  }
> > > diff --git a/arch/powerpc/xmon/xmon_bpts.S
> > > b/arch/powerpc/xmon/xmon_bpts.S
> > > index ebb2dbc70ca8..09058eb6abbd 100644
> > > --- a/arch/powerpc/xmon/xmon_bpts.S
> > > +++ b/arch/powerpc/xmon/xmon_bpts.S
> > > @@ -3,6 +3,8 @@
> > >  #include <asm/asm-compat.h>
> > >  #include "xmon_bpts.h"
> > > 
> > > +/* Prefixed instructions can not cross 64 byte boundaries */
> > > +.align 6
> > >  .global bpt_table
> > >  bpt_table:
> > > -     .space NBPTS * 8
> > > +     .space NBPTS * 16


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

end of thread, other threads:[~2020-04-15  8:17 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-06  8:09 [PATCH v5 00/21] Initial Prefixed Instruction support Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 01/21] powerpc/xmon: Remove store_inst() for patch_instruction() Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 02/21] powerpc/xmon: Move out-of-line instructions to text section Jordan Niethe
2020-04-07  6:45   ` Balamuruhan S
2020-04-09  6:11   ` Christophe Leroy
2020-04-09  7:26     ` Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 03/21] powerpc: Change calling convention for create_branch() et. al Jordan Niethe
2020-04-06 10:25   ` kbuild test robot
2020-04-06 10:25     ` kbuild test robot
2020-04-07  6:10   ` Balamuruhan S
2020-04-07  6:35     ` Jordan Niethe
2020-04-07  6:59       ` Balamuruhan S
2020-04-06  8:09 ` [PATCH v5 04/21] powerpc: Use a macro for creating instructions from u32s Jordan Niethe
2020-04-07  6:40   ` Balamuruhan S
2020-04-07  8:27     ` Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 05/21] powerpc: Use a function for getting the instruction op code Jordan Niethe
2020-04-06  8:22   ` Christophe Leroy
2020-04-06  9:38     ` Jordan Niethe
2020-04-07  7:04   ` Balamuruhan S
2020-04-07  8:32     ` Jordan Niethe
2020-04-08 18:21   ` Segher Boessenkool
2020-04-09  4:48     ` Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 06/21] powerpc: Use an accessor for instructions Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 07/21] powerpc: Use a function for byte swapping instructions Jordan Niethe
2020-04-07  7:42   ` Balamuruhan S
2020-04-06  8:09 ` [PATCH v5 08/21] powerpc: Introduce functions for instruction equality Jordan Niethe
2020-04-07  7:37   ` Balamuruhan S
2020-04-06  8:09 ` [PATCH v5 09/21] powerpc: Use a datatype for instructions Jordan Niethe
2020-04-06 10:34   ` kbuild test robot
2020-04-06 10:34     ` kbuild test robot
2020-04-06 10:35   ` kbuild test robot
2020-04-06 10:35     ` kbuild test robot
2020-04-07 10:30   ` Balamuruhan S
2020-04-08  2:11     ` Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 10/21] powerpc: Use a function for reading instructions Jordan Niethe
2020-04-07 10:42   ` Balamuruhan S
2020-04-06  8:09 ` [PATCH v5 11/21] powerpc: Define and use __get_user_instr{, inatomic}() Jordan Niethe
2020-04-07 10:48   ` Balamuruhan S
2020-04-08  2:13     ` Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 12/21] powerpc: Introduce a function for reporting instruction length Jordan Niethe
2020-04-07 11:14   ` Balamuruhan S
2020-04-08  2:14     ` Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 13/21] powerpc/xmon: Use a function for reading instructions Jordan Niethe
2020-04-07 11:30   ` Balamuruhan S
2020-04-08  2:18     ` Jordan Niethe
2020-04-09  5:04       ` Balamuruhan S
2020-04-09  5:14         ` Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 14/21] powerpc/xmon: Move insertion of breakpoint for xol'ing Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 15/21] powerpc: Make test_translate_branch() independent of instruction length Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 16/21] powerpc: Enable Prefixed Instructions Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 17/21] powerpc: Define new SRR1 bits for a future ISA version Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type Jordan Niethe
2020-04-06  9:52   ` Alistair Popple
2020-04-06 10:25     ` Christophe Leroy
2020-04-06 11:13       ` Jordan Niethe
2020-04-08 18:11       ` Segher Boessenkool
2020-04-08 18:43         ` Christophe Leroy
2020-04-06 10:42     ` Jordan Niethe
2020-04-07  1:39       ` Alistair Popple
2020-04-06 11:04   ` kbuild test robot
2020-04-06 11:04     ` kbuild test robot
2020-04-13 12:04   ` Balamuruhan S
2020-04-15  4:40     ` Jordan Niethe
2020-04-15  8:14       ` Balamuruhan S
2020-04-06  8:09 ` [PATCH v5 19/21] powerpc: Support prefixed instructions in alignment handler Jordan Niethe
2020-04-06  8:09 ` [PATCH v5 20/21] powerpc sstep: Add support for prefixed load/stores Jordan Niethe
2020-04-06 11:29   ` kbuild test robot
2020-04-06 11:29     ` kbuild test robot
2020-04-06  8:09 ` [PATCH v5 21/21] powerpc sstep: Add support for prefixed fixed-point arithmetic Jordan Niethe
2020-04-09  6:39 ` [PATCH v5 00/21] Initial Prefixed Instruction support Christophe Leroy
2020-04-09  7:28   ` Jordan Niethe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.