All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] powerpc: Enhance error handling with patch_instruction()
@ 2020-04-23 15:09 Naveen N. Rao
  2020-04-23 15:09 ` [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction() Naveen N. Rao
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-23 15:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Rostedt

This patchset updates error handling with patch_instruction(). The first 
patch fixes an issue with do_patch_instruction() with STRICT_KERNEL_RWX 
wherein errors were not being returned back. The second and third 
patches update users of patch_instruction() in ftrace and kprobes code 
to properly validate return value from patch_instruction() and to notify 
errors.

- Naveen

Naveen N. Rao (3):
  powerpc: Properly return error code from do_patch_instruction()
  powerpc/ftrace: Simplify error checking when patching instructions
  powerpc/kprobes: Check return value of patch_instruction()

 arch/powerpc/kernel/kprobes.c      | 10 ++-
 arch/powerpc/kernel/optprobes.c    | 99 ++++++++++++++++++++++++------
 arch/powerpc/kernel/trace/ftrace.c | 69 ++++++++++-----------
 arch/powerpc/lib/code-patching.c   |  6 +-
 4 files changed, 123 insertions(+), 61 deletions(-)


base-commit: 8299da600ad05b8aa0f15ec0f5f03bd40e37d6f0
-- 
2.25.1


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

* [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-23 15:09 [PATCH 0/3] powerpc: Enhance error handling with patch_instruction() Naveen N. Rao
@ 2020-04-23 15:09 ` Naveen N. Rao
  2020-04-23 16:21   ` Christophe Leroy
  2022-01-14 16:19   ` Christophe Leroy
  2020-04-23 15:09 ` [PATCH 2/3] powerpc/ftrace: Simplify error checking when patching instructions Naveen N. Rao
  2020-04-23 15:09 ` [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction() Naveen N. Rao
  2 siblings, 2 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-23 15:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Rostedt

With STRICT_KERNEL_RWX, we are currently ignoring return value from
__patch_instruction() in do_patch_instruction(), resulting in the error
not being propagated back. Fix the same.

Fixes: 37bc3e5fd764f ("powerpc/lib/code-patching: Use alternate map for patch_instruction()")
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 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 3345f039a876..5c713a6c0bd8 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -138,7 +138,7 @@ static inline int unmap_patch_area(unsigned long addr)
 
 static int do_patch_instruction(unsigned int *addr, unsigned int instr)
 {
-	int err;
+	int err, rc = 0;
 	unsigned int *patch_addr = NULL;
 	unsigned long flags;
 	unsigned long text_poke_addr;
@@ -163,7 +163,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
 	patch_addr = (unsigned int *)(text_poke_addr) +
 			((kaddr & ~PAGE_MASK) / sizeof(unsigned int));
 
-	__patch_instruction(addr, instr, patch_addr);
+	rc = __patch_instruction(addr, instr, patch_addr);
 
 	err = unmap_patch_area(text_poke_addr);
 	if (err)
@@ -172,7 +172,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
 out:
 	local_irq_restore(flags);
 
-	return err;
+	return rc ? rc : err;
 }
 #else /* !CONFIG_STRICT_KERNEL_RWX */
 
-- 
2.25.1


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

* [PATCH 2/3] powerpc/ftrace: Simplify error checking when patching instructions
  2020-04-23 15:09 [PATCH 0/3] powerpc: Enhance error handling with patch_instruction() Naveen N. Rao
  2020-04-23 15:09 ` [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction() Naveen N. Rao
@ 2020-04-23 15:09 ` Naveen N. Rao
  2020-04-23 15:44   ` Christophe Leroy
  2020-04-23 15:09 ` [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction() Naveen N. Rao
  2 siblings, 1 reply; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-23 15:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Rostedt

Introduce a macro PATCH_INSN() to simplify instruction patching, and to
make the error messages more uniform and useful:
- print an error message that includes the original return value
- print the function name and line numbers, so that the offending
  location is clear
- always return -EPERM, which ftrace_bug() expects for proper error
  handling

Also eliminate use of patch_branch() since most such uses already call
create_branch() for error checking before patching. Instead, use the
return value from create_branch() with PATCH_INSN().

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/trace/ftrace.c | 69 ++++++++++++++----------------
 1 file changed, 33 insertions(+), 36 deletions(-)

diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 7ea0ca044b65..5cf84c0c64cb 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -31,6 +31,17 @@
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
+#define PATCH_INSN(addr, instr)						     \
+do {									     \
+	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
+	if (rc) {							     \
+		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
+				__func__, __LINE__,			     \
+				(void *)(addr), (void *)(addr), rc);	     \
+		return -EPERM;						     \
+	}								     \
+} while (0)
+
 /*
  * We generally only have a single long_branch tramp and at most 2 or 3 plt
  * tramps generated. But, we don't use the plt tramps currently. We also allot
@@ -78,8 +89,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))
-		return -EPERM;
+	PATCH_INSN(ip, new);
 
 	return 0;
 }
@@ -204,10 +214,7 @@ __ftrace_make_nop(struct module *mod,
 	}
 #endif /* CONFIG_MPROFILE_KERNEL */
 
-	if (patch_instruction((unsigned int *)ip, pop)) {
-		pr_err("Patching NOP failed.\n");
-		return -EPERM;
-	}
+	PATCH_INSN(ip, pop);
 
 	return 0;
 }
@@ -276,8 +283,7 @@ __ftrace_make_nop(struct module *mod,
 
 	op = PPC_INST_NOP;
 
-	if (patch_instruction((unsigned int *)ip, op))
-		return -EPERM;
+	PATCH_INSN(ip, op);
 
 	return 0;
 }
@@ -322,7 +328,7 @@ static int add_ftrace_tramp(unsigned long tramp)
  */
 static int setup_mcount_compiler_tramp(unsigned long tramp)
 {
-	int i, op;
+	unsigned int i, op;
 	unsigned long ptr;
 	static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
 
@@ -366,16 +372,14 @@ 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)) {
+	op = create_branch((void *)tramp, ptr, 0);
+	if (!op) {
 		pr_debug("%ps is not reachable from existing mcount tramp\n",
 				(void *)ptr);
 		return -1;
 	}
 
-	if (patch_branch((unsigned int *)tramp, ptr, 0)) {
-		pr_debug("REL24 out of range!\n");
-		return -1;
-	}
+	PATCH_INSN(tramp, op);
 
 	if (add_ftrace_tramp(tramp)) {
 		pr_debug("No tramp locations left\n");
@@ -416,10 +420,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
 		}
 	}
 
-	if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) {
-		pr_err("Patching NOP failed.\n");
-		return -EPERM;
-	}
+	PATCH_INSN(ip, PPC_INST_NOP);
 
 	return 0;
 }
@@ -557,15 +558,13 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	/* Ensure branch is within 24 bits */
-	if (!create_branch(ip, tramp, BRANCH_SET_LINK)) {
+	op[0] = create_branch(ip, tramp, BRANCH_SET_LINK);
+	if (!op[0]) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
 
-	if (patch_branch(ip, tramp, BRANCH_SET_LINK)) {
-		pr_err("REL24 out of range!\n");
-		return -EINVAL;
-	}
+	PATCH_INSN(ip, op[0]);
 
 	return 0;
 }
@@ -603,8 +602,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 
 	pr_devel("write to %lx\n", rec->ip);
 
-	if (patch_instruction((unsigned int *)ip, op))
-		return -EPERM;
+	PATCH_INSN(ip, op);
 
 	return 0;
 }
@@ -650,11 +648,14 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
 		return -EINVAL;
 	}
 
-	if (patch_branch(ip, tramp, BRANCH_SET_LINK)) {
-		pr_err("Error patching branch to ftrace tramp!\n");
+	op = create_branch(ip, tramp, BRANCH_SET_LINK);
+	if (!op) {
+		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
 
+	PATCH_INSN(ip, op);
+
 	return 0;
 }
 
@@ -748,10 +749,8 @@ __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)) {
-			pr_err("REL24 out of range!\n");
-			return -EINVAL;
-		}
+		op = create_branch((unsigned int *)ip, addr, BRANCH_SET_LINK);
+		PATCH_INSN(ip, op);
 
 		return 0;
 	}
@@ -776,15 +775,13 @@ __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)) {
+	op = create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK);
+	if (!op) {
 		pr_err("Branch out of range\n");
 		return -EINVAL;
 	}
 
-	if (patch_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
-		pr_err("REL24 out of range!\n");
-		return -EINVAL;
-	}
+	PATCH_INSN(ip, op);
 
 	return 0;
 }
-- 
2.25.1


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

* [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-23 15:09 [PATCH 0/3] powerpc: Enhance error handling with patch_instruction() Naveen N. Rao
  2020-04-23 15:09 ` [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction() Naveen N. Rao
  2020-04-23 15:09 ` [PATCH 2/3] powerpc/ftrace: Simplify error checking when patching instructions Naveen N. Rao
@ 2020-04-23 15:09 ` Naveen N. Rao
  2020-04-23 15:41   ` Christophe Leroy
  2 siblings, 1 reply; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-23 15:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Steven Rostedt

patch_instruction() can fail in some scenarios. Add appropriate error
checking so that such failures are caught and logged, and suitable error
code is returned.

Fixes: d07df82c43be8 ("powerpc/kprobes: Move kprobes over to patch_instruction()")
Fixes: f3eca95638931 ("powerpc/kprobes/optprobes: Use patch_instruction()")
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/kprobes.c   | 10 +++-
 arch/powerpc/kernel/optprobes.c | 99 ++++++++++++++++++++++++++-------
 2 files changed, 87 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 81efb605113e..4a297ae2bd87 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -138,13 +138,19 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
 
 void arch_arm_kprobe(struct kprobe *p)
 {
-	patch_instruction(p->addr, BREAKPOINT_INSTRUCTION);
+	int rc = patch_instruction(p->addr, BREAKPOINT_INSTRUCTION);
+
+	if (rc)
+		WARN("Failed to patch trap at 0x%pK: %d\n", (void *)p->addr, rc);
 }
 NOKPROBE_SYMBOL(arch_arm_kprobe);
 
 void arch_disarm_kprobe(struct kprobe *p)
 {
-	patch_instruction(p->addr, p->opcode);
+	int rc = patch_instruction(p->addr, p->opcode);
+
+	if (rc)
+		WARN("Failed to remove trap at 0x%pK: %d\n", (void *)p->addr, rc);
 }
 NOKPROBE_SYMBOL(arch_disarm_kprobe);
 
diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index 024f7aad1952..046485bb0a52 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -139,52 +139,67 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
 	}
 }
 
+#define PATCH_INSN(addr, instr)						     \
+do {									     \
+	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
+	if (rc) {							     \
+		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
+				__func__, __LINE__,			     \
+				(void *)(addr), (void *)(addr), rc);	     \
+		return rc;						     \
+	}								     \
+} while (0)
+
 /*
  * emulate_step() requires insn to be emulated as
  * second parameter. Load register 'r4' with the
  * instruction.
  */
-void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr)
+static int 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) |
+	PATCH_INSN(addr, PPC_INST_ADDIS | ___PPC_RT(4) |
 			  ((val >> 16) & 0xffff));
 	addr++;
 
 	/* ori r4,r4,(insn)@l */
-	patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(4) |
+	PATCH_INSN(addr, PPC_INST_ORI | ___PPC_RA(4) |
 			  ___PPC_RS(4) | (val & 0xffff));
+
+	return 0;
 }
 
 /*
  * Generate instructions to load provided immediate 64-bit value
  * to register 'r3' and patch these instructions at 'addr'.
  */
-void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
+static int patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
 {
 	/* lis r3,(op)@highest */
-	patch_instruction(addr, PPC_INST_ADDIS | ___PPC_RT(3) |
+	PATCH_INSN(addr, PPC_INST_ADDIS | ___PPC_RT(3) |
 			  ((val >> 48) & 0xffff));
 	addr++;
 
 	/* ori r3,r3,(op)@higher */
-	patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(3) |
+	PATCH_INSN(addr, 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) |
+	PATCH_INSN(addr, 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) |
+	PATCH_INSN(addr, 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) |
+	PATCH_INSN(addr, PPC_INST_ORI | ___PPC_RA(3) |
 			  ___PPC_RS(3) | (val & 0xffff));
+
+	return 0;
 }
 
 int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
@@ -216,14 +231,18 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	 * be within 32MB on either side of the current instruction.
 	 */
 	b_offset = (unsigned long)buff - (unsigned long)p->addr;
-	if (!is_offset_in_branch_range(b_offset))
+	if (!is_offset_in_branch_range(b_offset)) {
+		rc = -ERANGE;
 		goto error;
+	}
 
 	/* Check if the return address is also within 32MB range */
 	b_offset = (unsigned long)(buff + TMPL_RET_IDX) -
 			(unsigned long)nip;
-	if (!is_offset_in_branch_range(b_offset))
+	if (!is_offset_in_branch_range(b_offset)) {
+		rc = -ERANGE;
 		goto error;
+	}
 
 	/* Setup template */
 	/* We can optimize this via patch_instruction_window later */
@@ -231,15 +250,22 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	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));
-		if (rc < 0)
+		if (rc) {
+			pr_err("%s: Error copying optprobe template to 0x%pK: %d\n",
+					__func__, (void *)(buff + i), rc);
+			rc = -EFAULT;
 			goto error;
+		}
 	}
 
 	/*
 	 * 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);
+	if (patch_imm64_load_insns((unsigned long)op, buff + TMPL_OP_IDX)) {
+		rc = -EFAULT;
+		goto error;
+	}
 
 	/*
 	 * 2. branch to optimized_callback() and emulate_step()
@@ -248,6 +274,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 	emulate_step_addr = (kprobe_opcode_t *)ppc_kallsyms_lookup_name("emulate_step");
 	if (!op_callback_addr || !emulate_step_addr) {
 		WARN(1, "Unable to lookup optimized_callback()/emulate_step()\n");
+		rc = -ERANGE;
 		goto error;
 	}
 
@@ -259,21 +286,48 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 				(unsigned long)emulate_step_addr,
 				BRANCH_SET_LINK);
 
-	if (!branch_op_callback || !branch_emulate_step)
+	if (!branch_op_callback || !branch_emulate_step) {
+		rc = -ERANGE;
 		goto error;
+	}
 
-	patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
-	patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step);
+	rc = patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
+	if (rc) {
+		pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
+				__func__, __LINE__,
+				(void *)(buff + TMPL_CALL_HDLR_IDX), rc);
+		rc = -EFAULT;
+		goto error;
+	}
+
+	rc = patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step);
+	if (rc) {
+		pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
+				__func__, __LINE__,
+				(void *)(buff + TMPL_EMULATE_IDX), rc);
+		rc = -EFAULT;
+		goto error;
+	}
 
 	/*
 	 * 3. load instruction to be emulated into relevant register, and
 	 */
-	patch_imm32_load_insns(*p->ainsn.insn, buff + TMPL_INSN_IDX);
+	if (patch_imm32_load_insns(*p->ainsn.insn, buff + TMPL_INSN_IDX)) {
+		rc = -EFAULT;
+		goto error;
+	}
 
 	/*
 	 * 4. branch back from trampoline
 	 */
-	patch_branch(buff + TMPL_RET_IDX, (unsigned long)nip, 0);
+	rc = patch_branch(buff + TMPL_RET_IDX, (unsigned long)nip, 0);
+	if (rc) {
+		pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
+				__func__, __LINE__,
+				(void *)(buff + TMPL_RET_IDX), rc);
+		rc = -EFAULT;
+		goto error;
+	}
 
 	flush_icache_range((unsigned long)buff,
 			   (unsigned long)(&buff[TMPL_END_IDX]));
@@ -284,7 +338,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
 
 error:
 	free_ppc_optinsn_slot(buff, 0);
-	return -ERANGE;
+	return rc;
 
 }
 
@@ -307,6 +361,7 @@ void arch_optimize_kprobes(struct list_head *oplist)
 {
 	struct optimized_kprobe *op;
 	struct optimized_kprobe *tmp;
+	int rc;
 
 	list_for_each_entry_safe(op, tmp, oplist, list) {
 		/*
@@ -315,9 +370,13 @@ void arch_optimize_kprobes(struct list_head *oplist)
 		 */
 		memcpy(op->optinsn.copied_insn, op->kp.addr,
 					       RELATIVEJUMP_SIZE);
-		patch_instruction(op->kp.addr,
+		rc = patch_instruction(op->kp.addr,
 			create_branch((unsigned int *)op->kp.addr,
 				      (unsigned long)op->optinsn.insn, 0));
+		if (rc)
+			pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
+					__func__, __LINE__,
+					(void *)(op->kp.addr), rc);
 		list_del_init(&op->list);
 	}
 }
-- 
2.25.1


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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-23 15:09 ` [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction() Naveen N. Rao
@ 2020-04-23 15:41   ` Christophe Leroy
  2020-04-24 13:22     ` Steven Rostedt
  0 siblings, 1 reply; 24+ messages in thread
From: Christophe Leroy @ 2020-04-23 15:41 UTC (permalink / raw)
  To: Naveen N. Rao, linuxppc-dev; +Cc: Steven Rostedt



Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
> patch_instruction() can fail in some scenarios. Add appropriate error
> checking so that such failures are caught and logged, and suitable error
> code is returned.
> 
> Fixes: d07df82c43be8 ("powerpc/kprobes: Move kprobes over to patch_instruction()")
> Fixes: f3eca95638931 ("powerpc/kprobes/optprobes: Use patch_instruction()")
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
> ---
>   arch/powerpc/kernel/kprobes.c   | 10 +++-
>   arch/powerpc/kernel/optprobes.c | 99 ++++++++++++++++++++++++++-------
>   2 files changed, 87 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 81efb605113e..4a297ae2bd87 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -138,13 +138,19 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
>   
>   void arch_arm_kprobe(struct kprobe *p)
>   {
> -	patch_instruction(p->addr, BREAKPOINT_INSTRUCTION);
> +	int rc = patch_instruction(p->addr, BREAKPOINT_INSTRUCTION);
> +
> +	if (rc)
> +		WARN("Failed to patch trap at 0x%pK: %d\n", (void *)p->addr, rc);
>   }
>   NOKPROBE_SYMBOL(arch_arm_kprobe);
>   
>   void arch_disarm_kprobe(struct kprobe *p)
>   {
> -	patch_instruction(p->addr, p->opcode);
> +	int rc = patch_instruction(p->addr, p->opcode);
> +
> +	if (rc)
> +		WARN("Failed to remove trap at 0x%pK: %d\n", (void *)p->addr, rc);
>   }
>   NOKPROBE_SYMBOL(arch_disarm_kprobe);
>   
> diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index 024f7aad1952..046485bb0a52 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -139,52 +139,67 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
>   	}
>   }
>   
> +#define PATCH_INSN(addr, instr)						     \
> +do {									     \
> +	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
> +	if (rc) {							     \
> +		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
> +				__func__, __LINE__,			     \
> +				(void *)(addr), (void *)(addr), rc);	     \
> +		return rc;						     \
> +	}								     \
> +} while (0)
> +

I hate this kind of macro which hides the "return".

What about keeping the return action in the caller ?

Otherwise, what about implementing something based on the use of goto, 
on the same model as unsafe_put_user() for instance ?


Christophe

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

* Re: [PATCH 2/3] powerpc/ftrace: Simplify error checking when patching instructions
  2020-04-23 15:09 ` [PATCH 2/3] powerpc/ftrace: Simplify error checking when patching instructions Naveen N. Rao
@ 2020-04-23 15:44   ` Christophe Leroy
  0 siblings, 0 replies; 24+ messages in thread
From: Christophe Leroy @ 2020-04-23 15:44 UTC (permalink / raw)
  To: Naveen N. Rao, linuxppc-dev; +Cc: Steven Rostedt



Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
> Introduce a macro PATCH_INSN() to simplify instruction patching, and to
> make the error messages more uniform and useful:
> - print an error message that includes the original return value
> - print the function name and line numbers, so that the offending
>    location is clear
> - always return -EPERM, which ftrace_bug() expects for proper error
>    handling
> 
> Also eliminate use of patch_branch() since most such uses already call
> create_branch() for error checking before patching. Instead, use the
> return value from create_branch() with PATCH_INSN().

I have the same comment here as for patch 3, this kind of macro hides 
the return action and can be dangerous.

What about implementing a macro that takes an explicit label as third 
argument and jump to that label in case of error ? On the same model as 
unsafe_put_user() ?

Christophe

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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-23 15:09 ` [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction() Naveen N. Rao
@ 2020-04-23 16:21   ` Christophe Leroy
  2020-04-24 13:15     ` Steven Rostedt
  2020-04-24 18:02     ` Naveen N. Rao
  2022-01-14 16:19   ` Christophe Leroy
  1 sibling, 2 replies; 24+ messages in thread
From: Christophe Leroy @ 2020-04-23 16:21 UTC (permalink / raw)
  To: Naveen N. Rao, linuxppc-dev; +Cc: Steven Rostedt



Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
> With STRICT_KERNEL_RWX, we are currently ignoring return value from
> __patch_instruction() in do_patch_instruction(), resulting in the error
> not being propagated back. Fix the same.

Good patch.

Be aware that there is ongoing work which tend to wanting to replace 
error reporting by BUG_ON() . See 
https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003

> 
> Fixes: 37bc3e5fd764f ("powerpc/lib/code-patching: Use alternate map for patch_instruction()")
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
> ---
>   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 3345f039a876..5c713a6c0bd8 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -138,7 +138,7 @@ static inline int unmap_patch_area(unsigned long addr)
>   
>   static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>   {
> -	int err;
> +	int err, rc = 0;
>   	unsigned int *patch_addr = NULL;
>   	unsigned long flags;
>   	unsigned long text_poke_addr;
> @@ -163,7 +163,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>   	patch_addr = (unsigned int *)(text_poke_addr) +
>   			((kaddr & ~PAGE_MASK) / sizeof(unsigned int));
>   
> -	__patch_instruction(addr, instr, patch_addr);
> +	rc = __patch_instruction(addr, instr, patch_addr);
>   
>   	err = unmap_patch_area(text_poke_addr);
>   	if (err)
> @@ -172,7 +172,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>   out:
>   	local_irq_restore(flags);
>   
> -	return err;
> +	return rc ? rc : err;

That's not really consistent. __patch_instruction() and 
unmap_patch_area() return a valid minus errno, while in case of 
map_patch_area() failure, err has value -1

>   }
>   #else /* !CONFIG_STRICT_KERNEL_RWX */
>   
> 

Christophe

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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-23 16:21   ` Christophe Leroy
@ 2020-04-24 13:15     ` Steven Rostedt
  2020-04-24 18:07       ` Naveen N. Rao
  2020-04-24 19:26       ` Christopher M. Riedl
  2020-04-24 18:02     ` Naveen N. Rao
  1 sibling, 2 replies; 24+ messages in thread
From: Steven Rostedt @ 2020-04-24 13:15 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: Naveen N. Rao, linuxppc-dev

On Thu, 23 Apr 2020 18:21:14 +0200
Christophe Leroy <christophe.leroy@c-s.fr> wrote:

> Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
> > With STRICT_KERNEL_RWX, we are currently ignoring return value from
> > __patch_instruction() in do_patch_instruction(), resulting in the error
> > not being propagated back. Fix the same.  
> 
> Good patch.
> 
> Be aware that there is ongoing work which tend to wanting to replace 
> error reporting by BUG_ON() . See 
> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003

Thanks for the reference. I still believe that WARN_ON() should be used in
99% of the cases, including here. And only do a BUG_ON() when you know
there's no recovering from it.

In fact, there's still BUG_ON()s in my code that I need to convert to
WARN_ON() (it was written when BUG_ON() was still acceptable ;-)

-- Steve

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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-23 15:41   ` Christophe Leroy
@ 2020-04-24 13:22     ` Steven Rostedt
  2020-04-24 18:26       ` Naveen N. Rao
  0 siblings, 1 reply; 24+ messages in thread
From: Steven Rostedt @ 2020-04-24 13:22 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: Naveen N. Rao, linuxppc-dev

On Thu, 23 Apr 2020 17:41:52 +0200
Christophe Leroy <christophe.leroy@c-s.fr> wrote:
  
> > diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> > index 024f7aad1952..046485bb0a52 100644
> > --- a/arch/powerpc/kernel/optprobes.c
> > +++ b/arch/powerpc/kernel/optprobes.c
> > @@ -139,52 +139,67 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
> >   	}
> >   }
> >   
> > +#define PATCH_INSN(addr, instr)						     \
> > +do {									     \
> > +	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
> > +	if (rc) {							     \
> > +		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
> > +				__func__, __LINE__,			     \
> > +				(void *)(addr), (void *)(addr), rc);	     \
> > +		return rc;						     \
> > +	}								     \
> > +} while (0)
> > +  
> 
> I hate this kind of macro which hides the "return".
> 
> What about keeping the return action in the caller ?
> 
> Otherwise, what about implementing something based on the use of goto, 
> on the same model as unsafe_put_user() for instance ?

#define PATCH_INSN(addr, instr) \
({
	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
	if (rc)								     \
		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
				__func__, __LINE__,			     \
				(void *)(addr), (void *)(addr), rc);	     \
	rc;								     \
})


Then you can just do:

	ret = PATCH_INSN(...);
	if (ret)
		return ret;

in the code.

-- Steve

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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-23 16:21   ` Christophe Leroy
  2020-04-24 13:15     ` Steven Rostedt
@ 2020-04-24 18:02     ` Naveen N. Rao
  1 sibling, 0 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-24 18:02 UTC (permalink / raw)
  To: Christophe Leroy, linuxppc-dev; +Cc: Steven Rostedt

Christophe Leroy wrote:
> 
> 
> Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
>> With STRICT_KERNEL_RWX, we are currently ignoring return value from
>> __patch_instruction() in do_patch_instruction(), resulting in the error
>> not being propagated back. Fix the same.
> 
> Good patch.
> 
> Be aware that there is ongoing work which tend to wanting to replace 
> error reporting by BUG_ON() . See 
> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003

Hah, I see that you pointed out this exact issue in your review there!

I had noticed this when Russell's series for STRICT_MODULE_RWX started 
causing kretprobe failures, due to one of the early boot-time patching 
failing silently.

I'll defer to Michael on which patch he prefers to take, between this 
one and the series you point out above.

> 
>> 
>> Fixes: 37bc3e5fd764f ("powerpc/lib/code-patching: Use alternate map for patch_instruction()")
>> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
>> ---
>>   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 3345f039a876..5c713a6c0bd8 100644
>> --- a/arch/powerpc/lib/code-patching.c
>> +++ b/arch/powerpc/lib/code-patching.c
>> @@ -138,7 +138,7 @@ static inline int unmap_patch_area(unsigned long addr)
>>   
>>   static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>>   {
>> -	int err;
>> +	int err, rc = 0;
>>   	unsigned int *patch_addr = NULL;
>>   	unsigned long flags;
>>   	unsigned long text_poke_addr;
>> @@ -163,7 +163,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>>   	patch_addr = (unsigned int *)(text_poke_addr) +
>>   			((kaddr & ~PAGE_MASK) / sizeof(unsigned int));
>>   
>> -	__patch_instruction(addr, instr, patch_addr);
>> +	rc = __patch_instruction(addr, instr, patch_addr);
>>   
>>   	err = unmap_patch_area(text_poke_addr);
>>   	if (err)
>> @@ -172,7 +172,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>>   out:
>>   	local_irq_restore(flags);
>>   
>> -	return err;
>> +	return rc ? rc : err;
> 
> That's not really consistent. __patch_instruction() and 
> unmap_patch_area() return a valid minus errno, while in case of 
> map_patch_area() failure, err has value -1

Not sure I follow -- I'm not changing what would be returned in those 
cases, just also capturing return value from __patch_instruction().

If anything, I've considered the different return codes to be a good 
thing -- return code gives you a clear idea of what exactly failed.


- Naveen


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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-24 13:15     ` Steven Rostedt
@ 2020-04-24 18:07       ` Naveen N. Rao
  2020-04-24 18:29         ` Steven Rostedt
  2020-04-24 19:26       ` Christopher M. Riedl
  1 sibling, 1 reply; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-24 18:07 UTC (permalink / raw)
  To: Christophe Leroy, Steven Rostedt; +Cc: linuxppc-dev

Hi Steve,

Steven Rostedt wrote:
> On Thu, 23 Apr 2020 18:21:14 +0200
> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
> 
>> Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
>> > With STRICT_KERNEL_RWX, we are currently ignoring return value from
>> > __patch_instruction() in do_patch_instruction(), resulting in the error
>> > not being propagated back. Fix the same.  
>> 
>> Good patch.
>> 
>> Be aware that there is ongoing work which tend to wanting to replace 
>> error reporting by BUG_ON() . See 
>> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003
> 
> Thanks for the reference. I still believe that WARN_ON() should be used in
> 99% of the cases, including here. And only do a BUG_ON() when you know
> there's no recovering from it.

I'm not sure if you meant that we should have a WARN_ON() in 
patch_instruction(), or if it was about the users of 
patch_instruction(). As you're well aware, ftrace likes to do its own 
WARN_ON() if any of its operations fail through ftrace_bug(). That was 
the reason I didn't add anything here.


- Naveen

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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-24 13:22     ` Steven Rostedt
@ 2020-04-24 18:26       ` Naveen N. Rao
  2020-04-24 18:31         ` Steven Rostedt
  2020-04-25 10:11         ` Christophe Leroy
  0 siblings, 2 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-24 18:26 UTC (permalink / raw)
  To: Christophe Leroy, Steven Rostedt; +Cc: linuxppc-dev

Steven Rostedt wrote:
> On Thu, 23 Apr 2020 17:41:52 +0200
> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>   
>> > diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
>> > index 024f7aad1952..046485bb0a52 100644
>> > --- a/arch/powerpc/kernel/optprobes.c
>> > +++ b/arch/powerpc/kernel/optprobes.c
>> > @@ -139,52 +139,67 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
>> >   	}
>> >   }
>> >   
>> > +#define PATCH_INSN(addr, instr)						     \
>> > +do {									     \
>> > +	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
>> > +	if (rc) {							     \
>> > +		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
>> > +				__func__, __LINE__,			     \
>> > +				(void *)(addr), (void *)(addr), rc);	     \
>> > +		return rc;						     \
>> > +	}								     \
>> > +} while (0)
>> > +  
>> 
>> I hate this kind of macro which hides the "return".
>> 
>> What about keeping the return action in the caller ?
>> 
>> Otherwise, what about implementing something based on the use of goto, 
>> on the same model as unsafe_put_user() for instance ?

Thanks for the review.

I noticed this as a warning from checkpatch.pl, but this looked compact 
and correct for use in the two following functions. You'll notice that I 
added it just before the two functions this is used in.

I suppose 'goto err' is usable too, but the ftrace code (patch 2) will 
end up with more changes. I'm also struggling to see how a 'goto' is 
less offensive. I think Steve's suggestion below would be the better way 
to go, to make things explicit.

> 
> #define PATCH_INSN(addr, instr) \
> ({
> 	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
> 	if (rc)								     \
> 		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
> 				__func__, __LINE__,			     \
> 				(void *)(addr), (void *)(addr), rc);	     \
> 	rc;								     \
> })
> 
> 
> Then you can just do:
> 
> 	ret = PATCH_INSN(...);
> 	if (ret)
> 		return ret;
> 
> in the code.

That's really nice. However, in this case, I guess I can simply use an 
inline function? The primary reason I used the macro was for including a 
'return' statement in it.


Thanks for the review!
- Naveen


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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-24 18:07       ` Naveen N. Rao
@ 2020-04-24 18:29         ` Steven Rostedt
  0 siblings, 0 replies; 24+ messages in thread
From: Steven Rostedt @ 2020-04-24 18:29 UTC (permalink / raw)
  To: Naveen N. Rao; +Cc: linuxppc-dev

On Fri, 24 Apr 2020 23:37:06 +0530
"Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> wrote:

> >> Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :  
> >> > With STRICT_KERNEL_RWX, we are currently ignoring return value from
> >> > __patch_instruction() in do_patch_instruction(), resulting in the error
> >> > not being propagated back. Fix the same.    
> >> 
> >> Good patch.
> >> 
> >> Be aware that there is ongoing work which tend to wanting to replace 
> >> error reporting by BUG_ON() . See 
> >> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003  
> > 
> > Thanks for the reference. I still believe that WARN_ON() should be used in
> > 99% of the cases, including here. And only do a BUG_ON() when you know
> > there's no recovering from it.  
> 
> I'm not sure if you meant that we should have a WARN_ON() in 
> patch_instruction(), or if it was about the users of 
> patch_instruction(). As you're well aware, ftrace likes to do its own 
> WARN_ON() if any of its operations fail through ftrace_bug(). That was 
> the reason I didn't add anything here.

I'm fine with that too, and better reason not to call BUG_ON(), because I'm
guessing if we crash, we never make it to the ftrace_bug() which reports
information that can be used to debug what went wrong.

-- Steve

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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-24 18:26       ` Naveen N. Rao
@ 2020-04-24 18:31         ` Steven Rostedt
  2020-04-24 19:38           ` Naveen N. Rao
  2020-04-25 10:11         ` Christophe Leroy
  1 sibling, 1 reply; 24+ messages in thread
From: Steven Rostedt @ 2020-04-24 18:31 UTC (permalink / raw)
  To: Naveen N. Rao; +Cc: linuxppc-dev

On Fri, 24 Apr 2020 23:56:25 +0530
"Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> wrote:

> > #define PATCH_INSN(addr, instr) \
> > ({
> > 	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
> > 	if (rc)								     \
> > 		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
> > 				__func__, __LINE__,			     \
> > 				(void *)(addr), (void *)(addr), rc);	     \
> > 	rc;								     \
> > })
> > 
> > 
> > Then you can just do:
> > 
> > 	ret = PATCH_INSN(...);
> > 	if (ret)
> > 		return ret;
> > 
> > in the code.  
> 
> That's really nice. However, in this case, I guess I can simply use an 
> inline function? The primary reason I used the macro was for including a 
> 'return' statement in it.

I thought the primary reason was the __func__, __LINE__ which wont work as
expected as an inline.

-- Steve

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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-24 13:15     ` Steven Rostedt
  2020-04-24 18:07       ` Naveen N. Rao
@ 2020-04-24 19:26       ` Christopher M. Riedl
  2020-04-25 14:10         ` Steven Rostedt
  2020-04-27 17:14         ` Naveen N. Rao
  1 sibling, 2 replies; 24+ messages in thread
From: Christopher M. Riedl @ 2020-04-24 19:26 UTC (permalink / raw)
  To: Steven Rostedt, Christophe Leroy; +Cc: Naveen N. Rao, linuxppc-dev

On Fri Apr 24, 2020 at 9:15 AM, Steven Rostedt wrote:
> On Thu, 23 Apr 2020 18:21:14 +0200
> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> 
> > Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
> > > With STRICT_KERNEL_RWX, we are currently ignoring return value from
> > > __patch_instruction() in do_patch_instruction(), resulting in the error
> > > not being propagated back. Fix the same.  
> > 
> > Good patch.
> > 
> > Be aware that there is ongoing work which tend to wanting to replace 
> > error reporting by BUG_ON() . See 
> > https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003
>
> 
> Thanks for the reference. I still believe that WARN_ON() should be used
> in
> 99% of the cases, including here. And only do a BUG_ON() when you know
> there's no recovering from it.
>
> 
> In fact, there's still BUG_ON()s in my code that I need to convert to
> WARN_ON() (it was written when BUG_ON() was still acceptable ;-)
>
Figured I'd chime in since I am working on that other series :) The
BUG_ON()s are _only_ in the init code to set things up to allow a
temporary mapping for patching a STRICT_RWX kernel later. There's no
ongoing work to "replace error reporting by BUG_ON()". If that initial
setup fails we cannot patch under STRICT_KERNEL_RWX at all which imo
warrants a BUG_ON(). I am still working on v2 of my RFC which does
return any __patch_instruction() error back to the caller of
patch_instruction() similar to this patch.
> 
> -- Steve
>
> 
>
> 


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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-24 18:31         ` Steven Rostedt
@ 2020-04-24 19:38           ` Naveen N. Rao
  0 siblings, 0 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-24 19:38 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: linuxppc-dev

Steven Rostedt wrote:
> On Fri, 24 Apr 2020 23:56:25 +0530
> "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> wrote:
> 
>> > #define PATCH_INSN(addr, instr) \
>> > ({
>> > 	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
>> > 	if (rc)								     \
>> > 		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
>> > 				__func__, __LINE__,			     \
>> > 				(void *)(addr), (void *)(addr), rc);	     \
>> > 	rc;								     \
>> > })
>> > 
>> > 
>> > Then you can just do:
>> > 
>> > 	ret = PATCH_INSN(...);
>> > 	if (ret)
>> > 		return ret;
>> > 
>> > in the code.  
>> 
>> That's really nice. However, in this case, I guess I can simply use an 
>> inline function? The primary reason I used the macro was for including a 
>> 'return' statement in it.
> 
> I thought the primary reason was the __func__, __LINE__ which wont work as
> expected as an inline.

Ugh, you're right indeed. I clearly didn't think it through. :facepalm:

I'll use this variant.


Regards,
Naveen


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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-24 18:26       ` Naveen N. Rao
  2020-04-24 18:31         ` Steven Rostedt
@ 2020-04-25 10:11         ` Christophe Leroy
  2020-04-25 14:06           ` Steven Rostedt
  2020-04-27 17:11           ` Naveen N. Rao
  1 sibling, 2 replies; 24+ messages in thread
From: Christophe Leroy @ 2020-04-25 10:11 UTC (permalink / raw)
  To: Naveen N. Rao, Steven Rostedt; +Cc: linuxppc-dev



On 04/24/2020 06:26 PM, Naveen N. Rao wrote:
> Steven Rostedt wrote:
>> On Thu, 23 Apr 2020 17:41:52 +0200
>> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>>> > diff --git a/arch/powerpc/kernel/optprobes.c 
>>> b/arch/powerpc/kernel/optprobes.c
>>> > index 024f7aad1952..046485bb0a52 100644
>>> > --- a/arch/powerpc/kernel/optprobes.c
>>> > +++ b/arch/powerpc/kernel/optprobes.c
>>> > @@ -139,52 +139,67 @@ void arch_remove_optimized_kprobe(struct 
>>> optimized_kprobe *op)
>>> >       }
>>> >   }
>>> > > +#define PATCH_INSN(addr, instr)                             \
>>> > +do {                                         \
>>> > +    int rc = patch_instruction((unsigned int *)(addr), 
>>> instr);         \
>>> > +    if (rc) {                                 \
>>> > +        pr_err("%s:%d Error patching instruction at 0x%pK (%pS): 
>>> %d\n", \
>>> > +                __func__, __LINE__,                 \
>>> > +                (void *)(addr), (void *)(addr), rc);         \
>>> > +        return rc;                             \
>>> > +    }                                     \
>>> > +} while (0)
>>> > +
>>> I hate this kind of macro which hides the "return".
>>>
>>> What about keeping the return action in the caller ?
>>>
>>> Otherwise, what about implementing something based on the use of 
>>> goto, on the same model as unsafe_put_user() for instance ?
> 
> Thanks for the review.
> 
> I noticed this as a warning from checkpatch.pl, but this looked compact 
> and correct for use in the two following functions. You'll notice that I 
> added it just before the two functions this is used in.
> 
> I suppose 'goto err' is usable too, but the ftrace code (patch 2) will 
> end up with more changes. I'm also struggling to see how a 'goto' is 
> less offensive. I think Steve's suggestion below would be the better way 
> to go, to make things explicit.
> 

Sure it's be more explicit, but then more lines also. 3 lines for only 
one really usefull.

With goto, I would look like:

diff --git a/arch/powerpc/kernel/optprobes.c 
b/arch/powerpc/kernel/optprobes.c
index 046485bb0a52..938208f824da 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -139,14 +139,14 @@ void arch_remove_optimized_kprobe(struct 
optimized_kprobe *op)
  	}
  }

-#define PATCH_INSN(addr, instr)						     \
+#define PATCH_INSN(addr, instr, label)						     \
  do {									     \
  	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
  	if (rc) {							     \
  		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
  				__func__, __LINE__,			     \
  				(void *)(addr), (void *)(addr), rc);	     \
-		return rc;						     \
+		goto label;						     \
  	}								     \
  } while (0)

@@ -159,14 +159,17 @@ static int patch_imm32_load_insns(unsigned int 
val, kprobe_opcode_t *addr)
  {
  	/* addis r4,0,(insn)@h */
  	PATCH_INSN(addr, PPC_INST_ADDIS | ___PPC_RT(4) |
-			  ((val >> 16) & 0xffff));
+			  ((val >> 16) & 0xffff), failed);
  	addr++;

  	/* ori r4,r4,(insn)@l */
  	PATCH_INSN(addr, PPC_INST_ORI | ___PPC_RA(4) |
-			  ___PPC_RS(4) | (val & 0xffff));
+			  ___PPC_RS(4) | (val & 0xffff), failed);

  	return 0;
+
+failed:
+	return -EFAULT;
  }

  /*
@@ -177,29 +180,32 @@ static int patch_imm64_load_insns(unsigned long 
val, kprobe_opcode_t *addr)
  {
  	/* lis r3,(op)@highest */
  	PATCH_INSN(addr, PPC_INST_ADDIS | ___PPC_RT(3) |
-			  ((val >> 48) & 0xffff));
+			  ((val >> 48) & 0xffff), failed);
  	addr++;

  	/* ori r3,r3,(op)@higher */
  	PATCH_INSN(addr, PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 32) & 0xffff));
+			  ___PPC_RS(3) | ((val >> 32) & 0xffff), failed);
  	addr++;

  	/* rldicr r3,r3,32,31 */
  	PATCH_INSN(addr, PPC_INST_RLDICR | ___PPC_RA(3) |
-			  ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31));
+			  ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31), failed);
  	addr++;

  	/* oris r3,r3,(op)@h */
  	PATCH_INSN(addr, PPC_INST_ORIS | ___PPC_RA(3) |
-			  ___PPC_RS(3) | ((val >> 16) & 0xffff));
+			  ___PPC_RS(3) | ((val >> 16) & 0xffff), failed);
  	addr++;

  	/* ori r3,r3,(op)@l */
  	PATCH_INSN(addr, PPC_INST_ORI | ___PPC_RA(3) |
-			  ___PPC_RS(3) | (val & 0xffff));
+			  ___PPC_RS(3) | (val & 0xffff), failed);

  	return 0;
+
+failed:
+	return -EFAULT;
  }

  int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct 
kprobe *p)
@@ -291,23 +297,8 @@ int arch_prepare_optimized_kprobe(struct 
optimized_kprobe *op, struct kprobe *p)
  		goto error;
  	}

-	rc = patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
-	if (rc) {
-		pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
-				__func__, __LINE__,
-				(void *)(buff + TMPL_CALL_HDLR_IDX), rc);
-		rc = -EFAULT;
-		goto error;
-	}
-
-	rc = patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step);
-	if (rc) {
-		pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
-				__func__, __LINE__,
-				(void *)(buff + TMPL_EMULATE_IDX), rc);
-		rc = -EFAULT;
-		goto error;
-	}
+	PATCH_INSN(buff + TMPL_CALL_HDLR_IDX, branch_op_callback, efault);
+	PATCH_INSN(buff + TMPL_EMULATE_IDX, branch_emulate_step, efault);

  	/*
  	 * 3. load instruction to be emulated into relevant register, and
@@ -336,6 +327,8 @@ int arch_prepare_optimized_kprobe(struct 
optimized_kprobe *op, struct kprobe *p)

  	return 0;

+efault:
+	rc = -EFAULT;
  error:
  	free_ppc_optinsn_slot(buff, 0);
  	return rc;


Christophe

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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-25 10:11         ` Christophe Leroy
@ 2020-04-25 14:06           ` Steven Rostedt
  2020-04-27 17:13             ` Naveen N. Rao
  2020-04-27 17:11           ` Naveen N. Rao
  1 sibling, 1 reply; 24+ messages in thread
From: Steven Rostedt @ 2020-04-25 14:06 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: Naveen N. Rao, linuxppc-dev

On Sat, 25 Apr 2020 10:11:56 +0000
Christophe Leroy <christophe.leroy@c-s.fr> wrote:
> 
> Sure it's be more explicit, but then more lines also. 3 lines for only 
> one really usefull.
> 
> With goto, I would look like:
> 
> diff --git a/arch/powerpc/kernel/optprobes.c 
> b/arch/powerpc/kernel/optprobes.c
> index 046485bb0a52..938208f824da 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -139,14 +139,14 @@ void arch_remove_optimized_kprobe(struct 
> optimized_kprobe *op)
>   	}
>   }
> 
> -#define PATCH_INSN(addr, instr)						     \
> +#define PATCH_INSN(addr, instr, label)						     \

With the explicit label as a parameter, makes it more evident that it
will do something (like jump) with that label.

I like this solution the best!

-- Steve


>   do {									     \
>   	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
>   	if (rc) {							     \
>   		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
>   				__func__, __LINE__,			     \
>   				(void *)(addr), (void *)(addr), rc);	     \
> -		return rc;						     \
> +		goto label;						     \
>   	}								     \
>   } while (0)
> 

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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-24 19:26       ` Christopher M. Riedl
@ 2020-04-25 14:10         ` Steven Rostedt
  2020-04-25 14:11           ` Steven Rostedt
  2020-04-27 17:14         ` Naveen N. Rao
  1 sibling, 1 reply; 24+ messages in thread
From: Steven Rostedt @ 2020-04-25 14:10 UTC (permalink / raw)
  To: Christopher M. Riedl; +Cc: Naveen N. Rao, linuxppc-dev

On Fri, 24 Apr 2020 14:26:02 -0500
"Christopher M. Riedl" <cmr@informatik.wtf> wrote:

> On Fri Apr 24, 2020 at 9:15 AM, Steven Rostedt wrote:
> > On Thu, 23 Apr 2020 18:21:14 +0200
> > Christophe Leroy <christophe.leroy@c-s.fr> wrote:
> >
> >   
> > > Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :  
> > > > With STRICT_KERNEL_RWX, we are currently ignoring return value from
> > > > __patch_instruction() in do_patch_instruction(), resulting in the error
> > > > not being propagated back. Fix the same.    
> > > 
> > > Good patch.
> > > 
> > > Be aware that there is ongoing work which tend to wanting to replace 
> > > error reporting by BUG_ON() . See 
> > > https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003  
> >
> > 
> > Thanks for the reference. I still believe that WARN_ON() should be used
> > in
> > 99% of the cases, including here. And only do a BUG_ON() when you know
> > there's no recovering from it.
> >
> > 
> > In fact, there's still BUG_ON()s in my code that I need to convert to
> > WARN_ON() (it was written when BUG_ON() was still acceptable ;-)
> >  
> Figured I'd chime in since I am working on that other series :) The
> BUG_ON()s are _only_ in the init code to set things up to allow a
> temporary mapping for patching a STRICT_RWX kernel later. There's no
> ongoing work to "replace error reporting by BUG_ON()". If that initial
> setup fails we cannot patch under STRICT_KERNEL_RWX at all which imo
> warrants a BUG_ON(). I am still working on v2 of my RFC which does
> return any __patch_instruction() error back to the caller of
> patch_instruction() similar to this patch.


I agree certain locations may warrant a BUG_ON(), but I wouldn't make a
generic operation like patch_instruction() BUG, as it may be used in
cases that do not warrant it (like setting up ftrace).

Deciding to BUG on not based on the return code of patch_instruction()
is the way to go IMO.

-- Steve


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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-25 14:10         ` Steven Rostedt
@ 2020-04-25 14:11           ` Steven Rostedt
  0 siblings, 0 replies; 24+ messages in thread
From: Steven Rostedt @ 2020-04-25 14:11 UTC (permalink / raw)
  To: Christopher M. Riedl; +Cc: Naveen N. Rao, linuxppc-dev

On Sat, 25 Apr 2020 10:10:14 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> Deciding to BUG on not based on the return code of patch_instruction()

That was suppose to be "to BUG on or not,"

-- Steve

> is the way to go IMO.


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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-25 10:11         ` Christophe Leroy
  2020-04-25 14:06           ` Steven Rostedt
@ 2020-04-27 17:11           ` Naveen N. Rao
  1 sibling, 0 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-27 17:11 UTC (permalink / raw)
  To: Christophe Leroy, Steven Rostedt; +Cc: linuxppc-dev

Christophe Leroy wrote:
> 
> 
> On 04/24/2020 06:26 PM, Naveen N. Rao wrote:
>> Steven Rostedt wrote:
>>> On Thu, 23 Apr 2020 17:41:52 +0200
>>> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>>>> > diff --git a/arch/powerpc/kernel/optprobes.c 
>>>> b/arch/powerpc/kernel/optprobes.c
>>>> > index 024f7aad1952..046485bb0a52 100644
>>>> > --- a/arch/powerpc/kernel/optprobes.c
>>>> > +++ b/arch/powerpc/kernel/optprobes.c
>>>> > @@ -139,52 +139,67 @@ void arch_remove_optimized_kprobe(struct 
>>>> optimized_kprobe *op)
>>>> >       }
>>>> >   }
>>>> > > +#define PATCH_INSN(addr, instr)                             \
>>>> > +do {                                         \
>>>> > +    int rc = patch_instruction((unsigned int *)(addr), 
>>>> instr);         \
>>>> > +    if (rc) {                                 \
>>>> > +        pr_err("%s:%d Error patching instruction at 0x%pK (%pS): 
>>>> %d\n", \
>>>> > +                __func__, __LINE__,                 \
>>>> > +                (void *)(addr), (void *)(addr), rc);         \
>>>> > +        return rc;                             \
>>>> > +    }                                     \
>>>> > +} while (0)
>>>> > +
>>>> I hate this kind of macro which hides the "return".
>>>>
>>>> What about keeping the return action in the caller ?
>>>>
>>>> Otherwise, what about implementing something based on the use of 
>>>> goto, on the same model as unsafe_put_user() for instance ?
>> 
>> Thanks for the review.
>> 
>> I noticed this as a warning from checkpatch.pl, but this looked compact 
>> and correct for use in the two following functions. You'll notice that I 
>> added it just before the two functions this is used in.
>> 
>> I suppose 'goto err' is usable too, but the ftrace code (patch 2) will 
>> end up with more changes. I'm also struggling to see how a 'goto' is 
>> less offensive. I think Steve's suggestion below would be the better way 
>> to go, to make things explicit.
>> 
> 
> Sure it's be more explicit, but then more lines also. 3 lines for only 
> one really usefull.
> 
> With goto, I would look like:
> 
> diff --git a/arch/powerpc/kernel/optprobes.c 
> b/arch/powerpc/kernel/optprobes.c
> index 046485bb0a52..938208f824da 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -139,14 +139,14 @@ void arch_remove_optimized_kprobe(struct 
> optimized_kprobe *op)
>   	}
>   }
> 
> -#define PATCH_INSN(addr, instr)						     \
> +#define PATCH_INSN(addr, instr, label)						     \
>   do {									     \
>   	int rc = patch_instruction((unsigned int *)(addr), instr);	     \
>   	if (rc) {							     \
>   		pr_err("%s:%d Error patching instruction at 0x%pK (%pS): %d\n", \
>   				__func__, __LINE__,			     \
>   				(void *)(addr), (void *)(addr), rc);	     \
> -		return rc;						     \
> +		goto label;						     \
>   	}								     \
>   } while (0)

My earlier complaint was that this would still add a flow control 
statement, so didn't look to immediately address your original concern.  
However, I suppose introduction of an explicit label makes things a bit 
better.

In addition:

<snip>
> @@ -291,23 +297,8 @@ int arch_prepare_optimized_kprobe(struct 
> optimized_kprobe *op, struct kprobe *p)
>   		goto error;
>   	}
> 
> -	rc = patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
> -	if (rc) {
> -		pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
> -				__func__, __LINE__,
> -				(void *)(buff + TMPL_CALL_HDLR_IDX), rc);
> -		rc = -EFAULT;
> -		goto error;
> -	}
> -
> -	rc = patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step);
> -	if (rc) {
> -		pr_err("%s:%d: Error patching instruction at 0x%pK: %d\n",
> -				__func__, __LINE__,
> -				(void *)(buff + TMPL_EMULATE_IDX), rc);
> -		rc = -EFAULT;
> -		goto error;
> -	}
> +	PATCH_INSN(buff + TMPL_CALL_HDLR_IDX, branch_op_callback, efault);
> +	PATCH_INSN(buff + TMPL_EMULATE_IDX, branch_emulate_step, efault);

I like how this variant can cover additional uses of patch_instruction() 
here.

I will use this variant. Thanks for the suggestion!


- Naveen


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

* Re: [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction()
  2020-04-25 14:06           ` Steven Rostedt
@ 2020-04-27 17:13             ` Naveen N. Rao
  0 siblings, 0 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-27 17:13 UTC (permalink / raw)
  To: Christophe Leroy, Steven Rostedt; +Cc: linuxppc-dev

Steven Rostedt wrote:
> On Sat, 25 Apr 2020 10:11:56 +0000
> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>> 
>> Sure it's be more explicit, but then more lines also. 3 lines for only 
>> one really usefull.
>> 
>> With goto, I would look like:
>> 
>> diff --git a/arch/powerpc/kernel/optprobes.c 
>> b/arch/powerpc/kernel/optprobes.c
>> index 046485bb0a52..938208f824da 100644
>> --- a/arch/powerpc/kernel/optprobes.c
>> +++ b/arch/powerpc/kernel/optprobes.c
>> @@ -139,14 +139,14 @@ void arch_remove_optimized_kprobe(struct 
>> optimized_kprobe *op)
>>   	}
>>   }
>> 
>> -#define PATCH_INSN(addr, instr)						     \
>> +#define PATCH_INSN(addr, instr, label)						     \
> 
> With the explicit label as a parameter, makes it more evident that it
> will do something (like jump) with that label.

I think I will also rename the macro to PATCH_INSN_OR_GOTO() to make it 
super evident :)

> 
> I like this solution the best!

Thanks for the feedback.


- Naveen


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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-24 19:26       ` Christopher M. Riedl
  2020-04-25 14:10         ` Steven Rostedt
@ 2020-04-27 17:14         ` Naveen N. Rao
  1 sibling, 0 replies; 24+ messages in thread
From: Naveen N. Rao @ 2020-04-27 17:14 UTC (permalink / raw)
  To: Christophe Leroy, Christopher M. Riedl, Steven Rostedt; +Cc: linuxppc-dev

Christopher M. Riedl wrote:
> On Fri Apr 24, 2020 at 9:15 AM, Steven Rostedt wrote:
>> On Thu, 23 Apr 2020 18:21:14 +0200
>> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>>
>> 
>> > Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
>> > > With STRICT_KERNEL_RWX, we are currently ignoring return value from
>> > > __patch_instruction() in do_patch_instruction(), resulting in the error
>> > > not being propagated back. Fix the same.  
>> > 
>> > Good patch.
>> > 
>> > Be aware that there is ongoing work which tend to wanting to replace 
>> > error reporting by BUG_ON() . See 
>> > https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003
>>
>> 
>> Thanks for the reference. I still believe that WARN_ON() should be used
>> in
>> 99% of the cases, including here. And only do a BUG_ON() when you know
>> there's no recovering from it.
>>
>> 
>> In fact, there's still BUG_ON()s in my code that I need to convert to
>> WARN_ON() (it was written when BUG_ON() was still acceptable ;-)
>>
> Figured I'd chime in since I am working on that other series :) The
> BUG_ON()s are _only_ in the init code to set things up to allow a
> temporary mapping for patching a STRICT_RWX kernel later. There's no
> ongoing work to "replace error reporting by BUG_ON()". If that initial
> setup fails we cannot patch under STRICT_KERNEL_RWX at all which imo
> warrants a BUG_ON(). I am still working on v2 of my RFC which does
> return any __patch_instruction() error back to the caller of
> patch_instruction() similar to this patch.

Ok, that's good to know. I will drop this patch from my series, since 
this can be done independently of the other changes.

- Naveen


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

* Re: [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction()
  2020-04-23 15:09 ` [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction() Naveen N. Rao
  2020-04-23 16:21   ` Christophe Leroy
@ 2022-01-14 16:19   ` Christophe Leroy
  1 sibling, 0 replies; 24+ messages in thread
From: Christophe Leroy @ 2022-01-14 16:19 UTC (permalink / raw)
  To: Naveen N. Rao, linuxppc-dev; +Cc: Steven Rostedt



Le 23/04/2020 à 17:09, Naveen N. Rao a écrit :
> With STRICT_KERNEL_RWX, we are currently ignoring return value from
> __patch_instruction() in do_patch_instruction(), resulting in the error
> not being propagated back. Fix the same.
> 
> Fixes: 37bc3e5fd764f ("powerpc/lib/code-patching: Use alternate map for patch_instruction()")
> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>

A similar patch was merged as 
https://github.com/linuxppc/linux/commit/a3483c3dd18c136785a31406fe27210649fc4fba#diff-e084bb6dc223aec74e7fc4208b7b260acc571bd5b50c9b709ec3de175cb1a979

Christophe


> ---
>   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 3345f039a876..5c713a6c0bd8 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -138,7 +138,7 @@ static inline int unmap_patch_area(unsigned long addr)
>   
>   static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>   {
> -	int err;
> +	int err, rc = 0;
>   	unsigned int *patch_addr = NULL;
>   	unsigned long flags;
>   	unsigned long text_poke_addr;
> @@ -163,7 +163,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>   	patch_addr = (unsigned int *)(text_poke_addr) +
>   			((kaddr & ~PAGE_MASK) / sizeof(unsigned int));
>   
> -	__patch_instruction(addr, instr, patch_addr);
> +	rc = __patch_instruction(addr, instr, patch_addr);
>   
>   	err = unmap_patch_area(text_poke_addr);
>   	if (err)
> @@ -172,7 +172,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
>   out:
>   	local_irq_restore(flags);
>   
> -	return err;
> +	return rc ? rc : err;
>   }
>   #else /* !CONFIG_STRICT_KERNEL_RWX */
>   

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

end of thread, other threads:[~2022-01-14 16:19 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-23 15:09 [PATCH 0/3] powerpc: Enhance error handling with patch_instruction() Naveen N. Rao
2020-04-23 15:09 ` [PATCH 1/3] powerpc: Properly return error code from do_patch_instruction() Naveen N. Rao
2020-04-23 16:21   ` Christophe Leroy
2020-04-24 13:15     ` Steven Rostedt
2020-04-24 18:07       ` Naveen N. Rao
2020-04-24 18:29         ` Steven Rostedt
2020-04-24 19:26       ` Christopher M. Riedl
2020-04-25 14:10         ` Steven Rostedt
2020-04-25 14:11           ` Steven Rostedt
2020-04-27 17:14         ` Naveen N. Rao
2020-04-24 18:02     ` Naveen N. Rao
2022-01-14 16:19   ` Christophe Leroy
2020-04-23 15:09 ` [PATCH 2/3] powerpc/ftrace: Simplify error checking when patching instructions Naveen N. Rao
2020-04-23 15:44   ` Christophe Leroy
2020-04-23 15:09 ` [PATCH 3/3] powerpc/kprobes: Check return value of patch_instruction() Naveen N. Rao
2020-04-23 15:41   ` Christophe Leroy
2020-04-24 13:22     ` Steven Rostedt
2020-04-24 18:26       ` Naveen N. Rao
2020-04-24 18:31         ` Steven Rostedt
2020-04-24 19:38           ` Naveen N. Rao
2020-04-25 10:11         ` Christophe Leroy
2020-04-25 14:06           ` Steven Rostedt
2020-04-27 17:13             ` Naveen N. Rao
2020-04-27 17:11           ` Naveen N. Rao

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.