All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] harden idiv patching against undefined gcc behavior
@ 2016-03-10 18:19 Nicolas Pitre
  0 siblings, 0 replies; only message in thread
From: Nicolas Pitre @ 2016-03-10 18:19 UTC (permalink / raw)
  To: linux-arm-kernel

It was reported that a kernel with CONFIG_ARM_PATCH_IDIV=y stopped 
booting when compiled with the upcoming gcc 6.  Turns out that turning
a function address into a writable array is undefined and gcc 6 decided
it was OK to omit the store to the first word of the function while
still preserving the store to the second word.

Even though gcc 6 is now fixed to behave more coherently, it is a 
mystery that gcc 4 and gcc 5 actually produce wanted code in the kernel.  
And in fact the reduced test case to illustrate the issue does indeed 
break with gcc < 6 as well.

In any case, let's guard the kernel against undefined compiler behavior 
by hiding the nature of the array location as suggested by gcc 
developers.

Reference: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70128

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Reported-by: Marcin Juszkiewicz <mjuszkiewicz@redhat.com>


diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 7d0cba6f1c..c86ea8aac2 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -430,11 +430,13 @@ static void __init patch_aeabi_idiv(void)
 	pr_info("CPU: div instructions available: patching division code\n");
 
 	fn_addr = ((uintptr_t)&__aeabi_uidiv) & ~1;
+	asm ("" : "+g" (fn_addr));
 	((u32 *)fn_addr)[0] = udiv_instruction();
 	((u32 *)fn_addr)[1] = bx_lr_instruction();
 	flush_icache_range(fn_addr, fn_addr + 8);
 
 	fn_addr = ((uintptr_t)&__aeabi_idiv) & ~1;
+	asm ("" : "+g" (fn_addr));
 	((u32 *)fn_addr)[0] = sdiv_instruction();
 	((u32 *)fn_addr)[1] = bx_lr_instruction();
 	flush_icache_range(fn_addr, fn_addr + 8);

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2016-03-10 18:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-10 18:19 [PATCH] harden idiv patching against undefined gcc behavior Nicolas Pitre

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.