Re: [PATCH v5 10/21] powerpc: Use a function for reading instructions

2020-04-07 Thread Balamuruhan S
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 
> ---
> 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, ®s, *(struct ppc_inst *)p-
> >ainsn.insn) == 1) {
> + if (!is_conditional_branch(ppc_inst_read((struct ppc_inst *)p-
> >ainsn.insn)) &&
> + analyse_instr(&op, ®s, ppc_inst_read((struct
> ppc_inst *)p->ainsn.insn)) == 1) {
>   emulate_update_regs(®s, &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/

[PATCH v5 10/21] powerpc: Use a function for reading instructions

2020-04-06 Thread Jordan Niethe
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 
---
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, ®s, *(struct ppc_inst 
*)p->ainsn.insn) == 1) {
+   if (!is_conditional_branch(ppc_inst_read((struct ppc_inst 
*)p->ainsn.insn)) &&
+   analyse_instr(&op, ®s, ppc_inst_read((struct 
ppc_inst *)p->ainsn.insn)) == 1) {
emulate_update_regs(®s, &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 @@
 #defineNUM_FTRACE_TRAMPS   8
 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
 
+static long
+probe_kernel_read_inst(struct ppc_inst *inst, const void