[RFC] powerpc/lib: Fixing use a temporary mm for code patching
diff mbox series

Message ID c88b13ede49744d81fdab32e037a7ae10f0b241f.1585233657.git.christophe.leroy@c-s.fr
State RFC
Headers show
Series
  • [RFC] powerpc/lib: Fixing use a temporary mm for code patching
Related show

Checks

Context Check Description
snowpatch_ozlabs/apply_patch fail Failed to apply to any branch

Commit Message

Christophe Leroy March 26, 2020, 2:42 p.m. UTC
This patch fixes the RFC series identified below.
It fixes three points:
- Failure with CONFIG_PPC_KUAP
- Failure to write do to lack of DIRTY bit set on the 8xx
- Inadequaly complex WARN post verification

However, it has an impact on the CPU load. Here is the time
needed on an 8xx to run the ftrace selftests without and
with this series:
- Without CONFIG_STRICT_KERNEL_RWX		==> 38 seconds
- With CONFIG_STRICT_KERNEL_RWX			==> 40 seconds
- With CONFIG_STRICT_KERNEL_RWX + this series	==> 43 seconds

Link: https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=166003
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/lib/code-patching.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index f156132e8975..4ccff427592e 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -97,6 +97,7 @@  static int map_patch(const void *addr, struct patch_mapping *patch_mapping)
 	}
 
 	pte = mk_pte(page, pgprot);
+	pte = pte_mkdirty(pte);
 	set_pte_at(patching_mm, patching_addr, ptep, pte);
 
 	init_temp_mm(&patch_mapping->temp_mm, patching_mm);
@@ -168,7 +169,9 @@  static int do_patch_instruction(unsigned int *addr, unsigned int instr)
 			(offset_in_page((unsigned long)addr) /
 				sizeof(unsigned int));
 
+	allow_write_to_user(patch_addr, sizeof(instr));
 	__patch_instruction(addr, instr, patch_addr);
+	prevent_write_to_user(patch_addr, sizeof(instr));
 
 	err = unmap_patch(&patch_mapping);
 	if (err)
@@ -179,7 +182,7 @@  static int do_patch_instruction(unsigned int *addr, unsigned int instr)
 	 * think we just wrote.
 	 * XXX: BUG_ON() instead?
 	 */
-	WARN_ON(memcmp(addr, &instr, sizeof(instr)));
+	WARN_ON(*addr != instr);
 
 out:
 	local_irq_restore(flags);