Skip to contentSkip to conversation

arm64: psci: move psci firmware calls out of line

PATCH In review Kevin Hilman 1 participant 2 messages May 15, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 arm64: psci: move psci firmware calls out of line

From: Will Deacon <[email protected]>

An arm64 allmodconfig fails to build with GCC 5 due to __asmeq assertions in the PSCI firmware calling code firing due to mcount preambles breaking our assumptions about register allocation of function arguments:

/tmp/ccDqJsJ6.s: Assembler messages:
/tmp/ccDqJsJ6.s:60: Error: .err encountered
/tmp/ccDqJsJ6.s:61: Error: .err encountered
/tmp/ccDqJsJ6.s:62: Error: .err encountered
/tmp/ccDqJsJ6.s:99: Error: .err encountered
/tmp/ccDqJsJ6.s:100: Error: .err encountered
/tmp/ccDqJsJ6.s:101: Error: .err encountered

This patch fixes the issue by moving the PSCI calls out-of-line into their own assembly files, which are safe from the compiler's meddling fingers.

Cc <[email protected]> # v3.18
(cherry picked from commit f5e0a12ca2d939e47995f73428d9bf1ad372b289)

---
This commit is already applied to v3.19+ stable trees, but is also needed in v3.18, but didn't apply cleanly. This patch is a backport which fixed up a minor conflict in the Makefile so that it applies cleanly to v3.18.

 arch/arm64/kernel/Makefile    |  4 ++--
 arch/arm64/kernel/psci-call.S | 28 ++++++++++++++++++++++++++++
 arch/arm64/kernel/psci.c      | 37 +++----------------------------------
 3 files changed, 33 insertions(+), 36 deletions(-)
 create mode 100644 arch/arm64/kernel/psci-call.S
arch/arm64/kernel/Makefile +2 -2
index da2272811a31..eccb8c7cb30f 100644
@@ -14,8 +14,8 @@ CFLAGS_REMOVE_return_address.o = -pg
 arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
 			   entry-fpsimd.o process.o ptrace.o setup.o signal.o	\
 			   sys.o stacktrace.o time.o traps.o io.o vdso.o	\
-			   hyp-stub.o psci.o cpu_ops.o insn.o return_address.o	\
-			   cpuinfo.o cpu_errata.o alternative.o
+			   hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o 	\
+			   return_address.o cpuinfo.o cpu_errata.o alternative.o
 
 arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o
arch/arm64/kernel/psci-call.S new file +28 -0
new file mode 100644
index 000000000000..cf83e61cd3b5
@@ -0,0 +1,28 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2015 ARM Limited
+ *
+ * Author: Will Deacon <[email protected]>
+ */
+
+#include <linux/linkage.h>
+
+/* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
+ENTRY(__invoke_psci_fn_hvc)
+	hvc	#0
+	ret
+ENDPROC(__invoke_psci_fn_hvc)
+
+/* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
+ENTRY(__invoke_psci_fn_smc)
+	smc	#0
+	ret
+ENDPROC(__invoke_psci_fn_smc)
arch/arm64/kernel/psci.c +3 -34
index 663da771580a..81c081eaca42 100644
@@ -57,6 +57,9 @@ static struct psci_operations psci_ops;
 static int (*invoke_psci_fn)(u64, u64, u64, u64);
 typedef int (*psci_initcall_t)(const struct device_node *);
 
+asmlinkage int __invoke_psci_fn_hvc(u64, u64, u64, u64);
+asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64);
+
 enum psci_function {
 	PSCI_FN_CPU_SUSPEND,
 	PSCI_FN_CPU_ON,
@@ -109,40 +112,6 @@ static void psci_power_state_unpack(u32 power_state,
 			PSCI_0_2_POWER_STATE_AFFL_SHIFT;
 }
 
-/*
- * The following two functions are invoked via the invoke_psci_fn pointer
- * and will not be inlined, allowing us to piggyback on the AAPCS.
- */
-static noinline int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1,
-					 u64 arg2)
-{
-	asm volatile(
-			__asmeq("%0", "x0")
-			__asmeq("%1", "x1")
-			__asmeq("%2", "x2")
-			__asmeq("%3", "x3")
-			"hvc	#0\n"
-		: "+r" (function_id)
-		: "r" (arg0), "r" (arg1), "r" (arg2));
-
-	return function_id;
-}
-
-static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
-					 u64 arg2)
-{
-	asm volatile(
-			__asmeq("%0", "x0")
-			__asmeq("%1", "x1")
-			__asmeq("%2", "x2")
-			__asmeq("%3", "x3")
-			"smc	#0\n"
-		: "+r" (function_id)
-		: "r" (arg0), "r" (arg1), "r" (arg2));
-
-	return function_id;
-}
-
 static int psci_get_version(void)
 {
 	int err;
Signature · 1 line
2.3.1
#1 lore raw
Quoted 25 lines · Kevin Hilman

From: Will Deacon <[email protected]>

An arm64 allmodconfig fails to build with GCC 5 due to __asmeq assertions in the PSCI firmware calling code firing due to mcount preambles breaking our assumptions about register allocation of function arguments:

/tmp/ccDqJsJ6.s: Assembler messages:
/tmp/ccDqJsJ6.s:60: Error: .err encountered
/tmp/ccDqJsJ6.s:61: Error: .err encountered
/tmp/ccDqJsJ6.s:62: Error: .err encountered
/tmp/ccDqJsJ6.s:99: Error: .err encountered
/tmp/ccDqJsJ6.s:100: Error: .err encountered
/tmp/ccDqJsJ6.s:101: Error: .err encountered

This patch fixes the issue by moving the PSCI calls out-of-line into their own assembly files, which are safe from the compiler's meddling fingers.

Cc <[email protected]> # v3.18
(cherry picked from commit f5e0a12ca2d939e47995f73428d9bf1ad372b289)
Quoted 5 lines

---
This commit is already applied to v3.19+ stable trees, but is also needed in v3.18, but didn't apply cleanly. This patch is a backport which fixed up a minor conflict in the Makefile so that it applies cleanly to v3.18.

Oops, please ignore this one. It was the wrong backport and will not apply cleanly to v3.18. I'll resend the right one shortly.

Kevin