* [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement
@ 2018-09-25 17:20 Julien Grall
2018-09-25 17:20 ` [PATCH v2 1/6] xen/arm: smccc-1.1: Make return values unsigned long Julien Grall
` (5 more replies)
0 siblings, 6 replies; 23+ messages in thread
From: Julien Grall @ 2018-09-25 17:20 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, sstabellini, volodymyr_babchuk
Hi all,
This patch series contains fixup and improvement for the SMCCC subsystem.
Patch #1 - #2 are candidates for backporting.
Cheers,
Julien Grall (3):
xen/arm: cpufeature: Add helper to check constant caps
xen/arm: smccc: Add wrapper to automatically select the calling
convention
xen/arm: Replace call_smc with arm_smccc_smc
Marc Zyngier (2):
xen/arm: smccc-1.1: Make return values unsigned long
xen/arm: smccc-1.1: Handle function result as parameters
Volodymyr Babchuk (1):
xen/arm: add SMC wrapper that is compatible with SMCCC v1.0
xen/arch/arm/Makefile | 1 -
xen/arch/arm/arm64/Makefile | 1 +
xen/arch/arm/arm64/asm-offsets.c | 5 ++
xen/arch/arm/arm64/smc.S | 32 +++++++++++++
xen/arch/arm/platforms/exynos5.c | 3 +-
xen/arch/arm/platforms/seattle.c | 4 +-
xen/arch/arm/psci.c | 41 +++++++++++-----
xen/arch/arm/smc.S | 21 --------
xen/include/asm-arm/cpufeature.h | 15 +++++-
xen/include/asm-arm/processor.h | 3 --
xen/include/asm-arm/smccc.h | 100 +++++++++++++++++++++++++++++++++------
11 files changed, 170 insertions(+), 56 deletions(-)
create mode 100644 xen/arch/arm/arm64/smc.S
delete mode 100644 xen/arch/arm/smc.S
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 1/6] xen/arm: smccc-1.1: Make return values unsigned long
2018-09-25 17:20 [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement Julien Grall
@ 2018-09-25 17:20 ` Julien Grall
2018-09-25 23:18 ` Stefano Stabellini
2018-09-25 17:20 ` [PATCH v2 2/6] xen/arm: smccc-1.1: Handle function result as parameters Julien Grall
` (4 subsequent siblings)
5 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-25 17:20 UTC (permalink / raw)
To: xen-devel; +Cc: Marc Zyngier, Julien Grall, sstabellini, volodymyr_babchuk
From: Marc Zyngier <marc.zyngier@arm.com>
An unfortunate consequence of having a strong typing for the input
values to the SMC call is that it also affects the type of the
return values, limiting r0 to 32 bits and r{1,2,3} to whatever
was passed as an input.
Let's turn everything into "unsigned long", which satisfies the
requirements of both architectures, and allows for the full
range of return values.
Reported-by: Stefano Stabellini <stefanos@xilinx.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
---
Changes in v2:
- Add Volodymyr reviewed-by
---
xen/include/asm-arm/smccc.h | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
index 74c13f8419..a31d67a1de 100644
--- a/xen/include/asm-arm/smccc.h
+++ b/xen/include/asm-arm/smccc.h
@@ -119,35 +119,35 @@ struct arm_smccc_res {
#define __declare_arg_0(a0, res) \
struct arm_smccc_res *___res = res; \
- register uin32_t r0 asm("r0") = a0; \
+ register unsigned long r0 asm("r0") = (uint32_t)a0;\
register unsigned long r1 asm("r1"); \
register unsigned long r2 asm("r2"); \
register unsigned long r3 asm("r3")
#define __declare_arg_1(a0, a1, res) \
struct arm_smccc_res *___res = res; \
- register uint32_t r0 asm("r0") = a0; \
- register typeof(a1) r1 asm("r1") = a1; \
+ register unsigned long r0 asm("r0") = (uint32_t)a0;\
+ register unsigned long r1 asm("r1") = a1; \
register unsigned long r2 asm("r2"); \
register unsigned long r3 asm("r3")
#define __declare_arg_2(a0, a1, a2, res) \
struct arm_smccc_res *___res = res; \
- register u32 r0 asm("r0") = a0; \
- register typeof(a1) r1 asm("r1") = a1; \
- register typeof(a2) r2 asm("r2") = a2; \
+ register unsigned long r0 asm("r0") = (uint32_t)a0;\
+ register unsigned long r1 asm("r1") = a1; \
+ register unsigned long r2 asm("r2") = a2; \
register unsigned long r3 asm("r3")
#define __declare_arg_3(a0, a1, a2, a3, res) \
struct arm_smccc_res *___res = res; \
- register u32 r0 asm("r0") = a0; \
- register typeof(a1) r1 asm("r1") = a1; \
- register typeof(a2) r2 asm("r2") = a2; \
- register typeof(a3) r3 asm("r3") = a3
+ register unsigned long r0 asm("r0") = (uint32_t)a0;\
+ register unsigned long r1 asm("r1") = a1; \
+ register unsigned long r2 asm("r2") = a2; \
+ register unsigned long r3 asm("r3") = a3
#define __declare_arg_4(a0, a1, a2, a3, a4, res) \
__declare_arg_3(a0, a1, a2, a3, res); \
- register typeof(a4) r4 asm("r4") = a4
+ register unsigned long r4 asm("r4") = a4
#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
__declare_arg_4(a0, a1, a2, a3, a4, res); \
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 2/6] xen/arm: smccc-1.1: Handle function result as parameters
2018-09-25 17:20 [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement Julien Grall
2018-09-25 17:20 ` [PATCH v2 1/6] xen/arm: smccc-1.1: Make return values unsigned long Julien Grall
@ 2018-09-25 17:20 ` Julien Grall
2018-09-25 23:18 ` Stefano Stabellini
2018-09-25 17:20 ` [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0 Julien Grall
` (3 subsequent siblings)
5 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-25 17:20 UTC (permalink / raw)
To: xen-devel; +Cc: Marc Zyngier, sstabellini, volodymyr_babchuk
From: Marc Zyngier <marc.zyngier@arm.com>
If someone has the silly idea to write something along those lines:
extern u64 foo(void);
void bar(struct arm_smccc_res *res)
{
arm_smccc_1_1_smc(0xbad, foo(), res);
}
they are in for a surprise, as this gets compiled as:
0000000000000588 <bar>:
588: a9be7bfd stp x29, x30, [sp, #-32]!
58c: 910003fd mov x29, sp
590: f9000bf3 str x19, [sp, #16]
594: aa0003f3 mov x19, x0
598: aa1e03e0 mov x0, x30
59c: 94000000 bl 0 <_mcount>
5a0: 94000000 bl 0 <foo>
5a4: aa0003e1 mov x1, x0
5a8: d4000003 smc #0x0
5ac: b4000073 cbz x19, 5b8 <bar+0x30>
5b0: a9000660 stp x0, x1, [x19]
5b4: a9010e62 stp x2, x3, [x19, #16]
5b8: f9400bf3 ldr x19, [sp, #16]
5bc: a8c27bfd ldp x29, x30, [sp], #32
5c0: d65f03c0 ret
5c4: d503201f nop
The call to foo "overwrites" the x0 register for the return value,
and we end up calling the wrong secure service.
A solution is to evaluate all the parameters before assigning
anything to specific registers, leading to the expected result:
0000000000000588 <bar>:
588: a9be7bfd stp x29, x30, [sp, #-32]!
58c: 910003fd mov x29, sp
590: f9000bf3 str x19, [sp, #16]
594: aa0003f3 mov x19, x0
598: aa1e03e0 mov x0, x30
59c: 94000000 bl 0 <_mcount>
5a0: 94000000 bl 0 <foo>
5a4: aa0003e1 mov x1, x0
5a8: d28175a0 mov x0, #0xbad
5ac: d4000003 smc #0x0
5b0: b4000073 cbz x19, 5bc <bar+0x34>
5b4: a9000660 stp x0, x1, [x19]
5b8: a9010e62 stp x2, x3, [x19, #16]
5bc: f9400bf3 ldr x19, [sp, #16]
5c0: a8c27bfd ldp x29, x30, [sp], #32
5c4: d65f03c0 ret
Reported-by: Stefano Stabellini <stefanos@xilinx.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
---
Changes in v2:
- Add Volodymyr's reviewed-by
---
xen/include/asm-arm/smccc.h | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
index a31d67a1de..648bef28bd 100644
--- a/xen/include/asm-arm/smccc.h
+++ b/xen/include/asm-arm/smccc.h
@@ -125,41 +125,51 @@ struct arm_smccc_res {
register unsigned long r3 asm("r3")
#define __declare_arg_1(a0, a1, res) \
+ typeof(a1) __a1 = a1; \
struct arm_smccc_res *___res = res; \
register unsigned long r0 asm("r0") = (uint32_t)a0;\
- register unsigned long r1 asm("r1") = a1; \
+ register unsigned long r1 asm("r1") = __a1; \
register unsigned long r2 asm("r2"); \
register unsigned long r3 asm("r3")
#define __declare_arg_2(a0, a1, a2, res) \
+ typeof(a1) __a1 = a1; \
+ typeof(a2) __a2 = a2; \
struct arm_smccc_res *___res = res; \
register unsigned long r0 asm("r0") = (uint32_t)a0;\
- register unsigned long r1 asm("r1") = a1; \
- register unsigned long r2 asm("r2") = a2; \
+ register unsigned long r1 asm("r1") = __a1; \
+ register unsigned long r2 asm("r2") = __a2; \
register unsigned long r3 asm("r3")
#define __declare_arg_3(a0, a1, a2, a3, res) \
+ typeof(a1) __a1 = a1; \
+ typeof(a2) __a2 = a2; \
+ typeof(a3) __a3 = a3; \
struct arm_smccc_res *___res = res; \
register unsigned long r0 asm("r0") = (uint32_t)a0;\
- register unsigned long r1 asm("r1") = a1; \
- register unsigned long r2 asm("r2") = a2; \
- register unsigned long r3 asm("r3") = a3
+ register unsigned long r1 asm("r1") = __a1; \
+ register unsigned long r2 asm("r2") = __a2; \
+ register unsigned long r3 asm("r3") = __a3
#define __declare_arg_4(a0, a1, a2, a3, a4, res) \
+ typeof(a4) __a4 = a4; \
__declare_arg_3(a0, a1, a2, a3, res); \
- register unsigned long r4 asm("r4") = a4
+ register unsigned long r4 asm("r4") = __a4
#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
+ typeof(a5) __a5 = a5; \
__declare_arg_4(a0, a1, a2, a3, a4, res); \
- register typeof(a5) r5 asm("r5") = a5
+ register typeof(a5) r5 asm("r5") = __a5
#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \
+ typeof(a6) __a6 = a6; \
__declare_arg_5(a0, a1, a2, a3, a4, a5, res); \
- register typeof(a6) r6 asm("r6") = a6
+ register typeof(a6) r6 asm("r6") = __a6
#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
+ typeof(a7) __a7 = a7; \
__declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \
- register typeof(a7) r7 asm("r7") = a7
+ register typeof(a7) r7 asm("r7") = __a7
#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
#define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__)
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0
2018-09-25 17:20 [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement Julien Grall
2018-09-25 17:20 ` [PATCH v2 1/6] xen/arm: smccc-1.1: Make return values unsigned long Julien Grall
2018-09-25 17:20 ` [PATCH v2 2/6] xen/arm: smccc-1.1: Handle function result as parameters Julien Grall
@ 2018-09-25 17:20 ` Julien Grall
2018-09-25 23:50 ` Stefano Stabellini
2018-09-25 17:20 ` [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps Julien Grall
` (2 subsequent siblings)
5 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-25 17:20 UTC (permalink / raw)
To: xen-devel; +Cc: Edgar E. Iglesias, Julien Grall, sstabellini, volodymyr_babchuk
From: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Existing SMC wrapper call_smc() allows only 4 parameters and
returns only one value. This is enough for existing
use in PSCI code, but TEE mediator will need a call that is
fully compatible with ARM SMCCC v1.0.
This patch adds a wrapper for both arm32 and arm64. In the case of
arm32, the wrapper is just an alias to the ARM SMCCC v1.1 as the
convention is the same.
CC: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
[julien: Rework the wrapper to make it closer to SMCC 1.1 wrapper]
Signed-off-by: Julien Grall <julien.grall@arm.com>
---
xen/arch/arm/arm64/Makefile | 1 +
xen/arch/arm/arm64/asm-offsets.c | 5 ++++
xen/arch/arm/arm64/smc.S | 32 +++++++++++++++++++++++++
xen/include/asm-arm/smccc.h | 51 +++++++++++++++++++++++++++++++++++++++-
4 files changed, 88 insertions(+), 1 deletion(-)
create mode 100644 xen/arch/arm/arm64/smc.S
diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
index bb5c610b2a..c4f3a28a0d 100644
--- a/xen/arch/arm/arm64/Makefile
+++ b/xen/arch/arm/arm64/Makefile
@@ -8,6 +8,7 @@ obj-y += domain.o
obj-y += entry.o
obj-y += insn.o
obj-$(CONFIG_LIVEPATCH) += livepatch.o
+obj-y += smc.o
obj-y += smpboot.o
obj-y += traps.o
obj-y += vfp.o
diff --git a/xen/arch/arm/arm64/asm-offsets.c b/xen/arch/arm/arm64/asm-offsets.c
index 62833d8c8b..280ddb55bf 100644
--- a/xen/arch/arm/arm64/asm-offsets.c
+++ b/xen/arch/arm/arm64/asm-offsets.c
@@ -10,6 +10,7 @@
#include <xen/bitops.h>
#include <public/xen.h>
#include <asm/current.h>
+#include <asm/smccc.h>
#define DEFINE(_sym, _val) \
asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \
@@ -51,6 +52,10 @@ void __dummy__(void)
BLANK();
OFFSET(INITINFO_stack, struct init_info, stack);
+
+ BLANK();
+ OFFSET(SMCCC_RES_a0, struct arm_smccc_res, a0);
+ OFFSET(SMCCC_RES_a2, struct arm_smccc_res, a2);
}
/*
diff --git a/xen/arch/arm/arm64/smc.S b/xen/arch/arm/arm64/smc.S
new file mode 100644
index 0000000000..b0752be57e
--- /dev/null
+++ b/xen/arch/arm/arm64/smc.S
@@ -0,0 +1,32 @@
+/*
+ * xen/arch/arm/arm64/smc.S
+ *
+ * Wrapper for Secure Monitors Calls
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * 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.
+ */
+
+#include <asm/asm_defns.h>
+#include <asm/macros.h>
+
+/*
+ * void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
+ * register_t a3, register_t a4, register_t a5,
+ * register_t a6, register_t a7,
+ * struct arm_smccc_res *res)
+ */
+ENTRY(__arm_smccc_1_0_smc)
+ smc #0
+ ldr x4, [sp]
+ cbz x4, 1f /* No need to store the result */
+ stp x0, x1, [x4, #SMCCC_RES_a0]
+ stp x2, x3, [x4, #SMCCC_RES_a2]
+1:
+ ret
diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
index 648bef28bd..1ed6cbaa48 100644
--- a/xen/include/asm-arm/smccc.h
+++ b/xen/include/asm-arm/smccc.h
@@ -207,7 +207,56 @@ struct arm_smccc_res {
*___res = (typeof(*___res)){r0, r1, r2, r3}; \
} while ( 0 )
-#endif
+/*
+ * The calling convention for arm32 is the same for both SMCCC v1.0 and
+ * v1.1.
+ */
+#ifdef CONFIG_ARM_32
+#define arm_smccc_1_0_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
+#else
+
+void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
+ register_t a3, register_t a4, register_t a5,
+ register_t a6, register_t a7,
+ struct arm_smccc_res *res);
+
+/* Macros to handle variadic parameter for SMCCC v1.0 helper */
+#define __arm_smccc_1_0_smc_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
+ __arm_smccc_1_0_smc(a0, a1, a2, a3, a4, a5, a6, a7, res)
+
+#define __arm_smccc_1_0_smc_6(a0, a1, a2, a3, a4, a5, a6, res) \
+ __arm_smccc_1_0_smc_7(a0, a1, a2, a3, a4, a5, a6, 0, res)
+
+#define __arm_smccc_1_0_smc_5(a0, a1, a2, a3, a4, a5, res) \
+ __arm_smccc_1_0_smc_6(a0, a1, a2, a3, a4, a5, 0, res)
+
+#define __arm_smccc_1_0_smc_4(a0, a1, a2, a3, a4, res) \
+ __arm_smccc_1_0_smc_5(a0, a1, a2, a3, a4, 0, res)
+
+#define __arm_smccc_1_0_smc_3(a0, a1, a2, a3, res) \
+ __arm_smccc_1_0_smc_4(a0, a1, a2, a3, 0, res)
+
+#define __arm_smccc_1_0_smc_2(a0, a1, a2, res) \
+ __arm_smccc_1_0_smc_3(a0, a1, a2, 0, res)
+
+#define __arm_smccc_1_0_smc_1(a0, a1, res) \
+ __arm_smccc_1_0_smc_2(a0, a1, 0, res)
+
+#define __arm_smccc_1_0_smc_0(a0, res) \
+ __arm_smccc_1_0_smc_1(a0, 0, res)
+
+#define ___arm_smccc_1_0_smc_count(count, ...) \
+ __arm_smccc_1_0_smc_ ## count(__VA_ARGS__)
+
+#define __arm_smccc_1_0_smc_count(count, ...) \
+ ___arm_smccc_1_0_smc_count(count, __VA_ARGS__)
+
+#define arm_smccc_1_0_smc(...) \
+ __arm_smccc_1_0_smc_count(__count_args(__VA_ARGS__), __VA_ARGS__)
+
+#endif /* CONFIG_ARM_64 */
+
+#endif /* __ASSEMBLY__ */
/*
* Construct function identifier from call type (fast or standard),
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps
2018-09-25 17:20 [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement Julien Grall
` (2 preceding siblings ...)
2018-09-25 17:20 ` [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0 Julien Grall
@ 2018-09-25 17:20 ` Julien Grall
2018-09-26 16:53 ` Stefano Stabellini
2018-09-25 17:20 ` [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention Julien Grall
2018-09-25 17:20 ` [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc Julien Grall
5 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-25 17:20 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, sstabellini, volodymyr_babchuk
Some capababilities are set right during boot and will never change
afterwards. At the moment, the function cpu_have_caps will check whether
the cap is enabled from the memory.
It is possible to avoid the load from the memory by using an
ALTERNATIVE. With that the check is just reduced to 1 instruction.
Signed-off-by: Julien Grall <julien.grall@arm.com>
---
This is the static key for the poor. At some point we might want to
introduce something similar to static key in Xen.
Changes in v2:
- Use unlikely
---
xen/include/asm-arm/cpufeature.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/xen/include/asm-arm/cpufeature.h b/xen/include/asm-arm/cpufeature.h
index 3de6b54301..c6cbc2ec84 100644
--- a/xen/include/asm-arm/cpufeature.h
+++ b/xen/include/asm-arm/cpufeature.h
@@ -63,6 +63,18 @@ static inline bool cpus_have_cap(unsigned int num)
return test_bit(num, cpu_hwcaps);
}
+/* System capability check for constant cap */
+#define cpus_have_const_cap(num) ({ \
+ bool __ret; \
+ \
+ asm volatile (ALTERNATIVE("mov %0, #0", \
+ "mov %0, #1", \
+ num) \
+ : "=r" (__ret)); \
+ \
+ unlikely(__ret); \
+ })
+
static inline void cpus_set_cap(unsigned int num)
{
if (num >= ARM_NCAPS)
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention
2018-09-25 17:20 [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement Julien Grall
` (3 preceding siblings ...)
2018-09-25 17:20 ` [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps Julien Grall
@ 2018-09-25 17:20 ` Julien Grall
2018-09-25 23:52 ` Stefano Stabellini
2018-09-26 11:24 ` Volodymyr Babchuk
2018-09-25 17:20 ` [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc Julien Grall
5 siblings, 2 replies; 23+ messages in thread
From: Julien Grall @ 2018-09-25 17:20 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, sstabellini, volodymyr_babchuk
Signed-off-by: Julien Grall <julien.grall@arm.com>
---
Changes in v2:
- Invert the condition
- Add missing includes
---
xen/arch/arm/psci.c | 4 ++++
xen/include/asm-arm/cpufeature.h | 3 ++-
xen/include/asm-arm/smccc.h | 11 +++++++++++
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
index 3cf5ecf0f3..941eec921b 100644
--- a/xen/arch/arm/psci.c
+++ b/xen/arch/arm/psci.c
@@ -21,6 +21,7 @@
#include <xen/types.h>
#include <xen/mm.h>
#include <xen/smp.h>
+#include <asm/cpufeature.h>
#include <asm/psci.h>
#include <asm/acpi.h>
@@ -118,6 +119,9 @@ static void __init psci_init_smccc(void)
smccc_ver = ret;
}
+ if ( smccc_ver >= SMCCC_VERSION(1, 1) )
+ cpus_set_cap(ARM_SMCCC_1_1);
+
printk(XENLOG_INFO "Using SMC Calling Convention v%u.%u\n",
SMCCC_VERSION_MAJOR(smccc_ver), SMCCC_VERSION_MINOR(smccc_ver));
}
diff --git a/xen/include/asm-arm/cpufeature.h b/xen/include/asm-arm/cpufeature.h
index c6cbc2ec84..2d82264427 100644
--- a/xen/include/asm-arm/cpufeature.h
+++ b/xen/include/asm-arm/cpufeature.h
@@ -44,8 +44,9 @@
#define SKIP_CTXT_SWITCH_SERROR_SYNC 6
#define ARM_HARDEN_BRANCH_PREDICTOR 7
#define ARM_SSBD 8
+#define ARM_SMCCC_1_1 9
-#define ARM_NCAPS 9
+#define ARM_NCAPS 10
#ifndef __ASSEMBLY__
diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
index 1ed6cbaa48..126399dd70 100644
--- a/xen/include/asm-arm/smccc.h
+++ b/xen/include/asm-arm/smccc.h
@@ -16,6 +16,9 @@
#ifndef __ASM_ARM_SMCCC_H__
#define __ASM_ARM_SMCCC_H__
+#include <asm/alternative.h>
+#include <asm/cpufeature.h>
+
#define SMCCC_VERSION_MAJOR_SHIFT 16
#define SMCCC_VERSION_MINOR_MASK \
((1U << SMCCC_VERSION_MAJOR_SHIFT) - 1)
@@ -213,6 +216,7 @@ struct arm_smccc_res {
*/
#ifdef CONFIG_ARM_32
#define arm_smccc_1_0_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
+#define arm_smccc_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
#else
void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
@@ -254,6 +258,13 @@ void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
#define arm_smccc_1_0_smc(...) \
__arm_smccc_1_0_smc_count(__count_args(__VA_ARGS__), __VA_ARGS__)
+#define arm_smccc_smc(...) \
+ do { \
+ if ( cpus_have_const_cap(ARM_SMCCC_1_1) ) \
+ arm_smccc_1_1_smc(__VA_ARGS__); \
+ else \
+ arm_smccc_1_0_smc(__VA_ARGS__); \
+ } while ( 0 )
#endif /* CONFIG_ARM_64 */
#endif /* __ASSEMBLY__ */
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc
2018-09-25 17:20 [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement Julien Grall
` (4 preceding siblings ...)
2018-09-25 17:20 ` [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention Julien Grall
@ 2018-09-25 17:20 ` Julien Grall
2018-09-25 23:57 ` Stefano Stabellini
5 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-25 17:20 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, sstabellini, volodymyr_babchuk
call_smc is a subset of arm_smccc_smc. Rather than having 2 methods to
do SMCCC call, replace all call to the former by the later.
Signed-off-by: Julien Grall <julien.grall@arm.com>
---
xen/arch/arm/Makefile | 1 -
xen/arch/arm/platforms/exynos5.c | 3 ++-
xen/arch/arm/platforms/seattle.c | 4 ++--
xen/arch/arm/psci.c | 37 +++++++++++++++++++++++++------------
xen/arch/arm/smc.S | 21 ---------------------
xen/include/asm-arm/processor.h | 3 ---
6 files changed, 29 insertions(+), 40 deletions(-)
delete mode 100644 xen/arch/arm/smc.S
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index b9b141dc84..37fa8268b3 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -39,7 +39,6 @@ obj-y += processor.o
obj-y += psci.o
obj-y += setup.o
obj-y += shutdown.o
-obj-y += smc.o
obj-y += smp.o
obj-y += smpboot.o
obj-y += sysctl.o
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index c15ecf80f5..e2c0b7b878 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -26,6 +26,7 @@
#include <asm/platforms/exynos5.h>
#include <asm/platform.h>
#include <asm/io.h>
+#include <asm/smccc.h>
static bool secure_firmware;
@@ -249,7 +250,7 @@ static int exynos5_cpu_up(int cpu)
iounmap(power);
if ( secure_firmware )
- call_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+ arm_smccc_smc(SMC_CMD_CPU1BOOT, cpu, NULL);
return cpu_up_send_sgi(cpu);
}
diff --git a/xen/arch/arm/platforms/seattle.c b/xen/arch/arm/platforms/seattle.c
index 893cc17972..64cc1868c2 100644
--- a/xen/arch/arm/platforms/seattle.c
+++ b/xen/arch/arm/platforms/seattle.c
@@ -33,12 +33,12 @@ static const char * const seattle_dt_compat[] __initconst =
*/
static void seattle_system_reset(void)
{
- call_smc(PSCI_0_2_FN32_SYSTEM_RESET, 0, 0, 0);
+ arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_RESET, NULL);
}
static void seattle_system_off(void)
{
- call_smc(PSCI_0_2_FN32_SYSTEM_OFF, 0, 0, 0);
+ arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_OFF, NULL);
}
PLATFORM_START(seattle, "SEATTLE")
diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
index 941eec921b..02737e6caa 100644
--- a/xen/arch/arm/psci.c
+++ b/xen/arch/arm/psci.c
@@ -42,42 +42,53 @@ uint32_t smccc_ver;
static uint32_t psci_cpu_on_nr;
+#define PSCI_RET(res) ((int32_t)(res).a0)
+
int call_psci_cpu_on(int cpu)
{
- return call_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(init_secondary), 0);
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(init_secondary),
+ &res);
+
+ return (int32_t)res.a0;
}
void call_psci_cpu_off(void)
{
if ( psci_ver > PSCI_VERSION(0, 1) )
{
- int errno;
+ struct arm_smccc_res res;
/* If successfull the PSCI cpu_off call doesn't return */
- errno = call_smc(PSCI_0_2_FN32_CPU_OFF, 0, 0, 0);
+ arm_smccc_smc(PSCI_0_2_FN32_CPU_OFF, &res);
panic("PSCI cpu off failed for CPU%d err=%d\n", smp_processor_id(),
- errno);
+ PSCI_RET(res));
}
}
void call_psci_system_off(void)
{
if ( psci_ver > PSCI_VERSION(0, 1) )
- call_smc(PSCI_0_2_FN32_SYSTEM_OFF, 0, 0, 0);
+ arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_OFF, NULL);
}
void call_psci_system_reset(void)
{
if ( psci_ver > PSCI_VERSION(0, 1) )
- call_smc(PSCI_0_2_FN32_SYSTEM_RESET, 0, 0, 0);
+ arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_RESET, NULL);
}
static int __init psci_features(uint32_t psci_func_id)
{
+ struct arm_smccc_res res;
+
if ( psci_ver < PSCI_VERSION(1, 0) )
return PSCI_NOT_SUPPORTED;
- return call_smc(PSCI_1_0_FN32_PSCI_FEATURES, psci_func_id, 0, 0);
+ arm_smccc_smc(PSCI_1_0_FN32_PSCI_FEATURES, psci_func_id, NULL);
+
+ return PSCI_RET(res);
}
static int __init psci_is_smc_method(const struct dt_device_node *psci)
@@ -112,11 +123,11 @@ static void __init psci_init_smccc(void)
if ( psci_features(ARM_SMCCC_VERSION_FID) != PSCI_NOT_SUPPORTED )
{
- uint32_t ret;
+ struct arm_smccc_res res;
- ret = call_smc(ARM_SMCCC_VERSION_FID, 0, 0, 0);
- if ( ret != ARM_SMCCC_NOT_SUPPORTED )
- smccc_ver = ret;
+ arm_smccc_smc(ARM_SMCCC_VERSION_FID, &res);
+ if ( PSCI_RET(res) != ARM_SMCCC_NOT_SUPPORTED )
+ smccc_ver = PSCI_RET(res);
}
if ( smccc_ver >= SMCCC_VERSION(1, 1) )
@@ -165,6 +176,7 @@ static int __init psci_init_0_2(void)
{ /* sentinel */ },
};
int ret;
+ struct arm_smccc_res res;
if ( acpi_disabled )
{
@@ -186,7 +198,8 @@ static int __init psci_init_0_2(void)
}
}
- psci_ver = call_smc(PSCI_0_2_FN32_PSCI_VERSION, 0, 0, 0);
+ arm_smccc_smc(PSCI_0_2_FN32_PSCI_VERSION, &res);
+ psci_ver = PSCI_RET(res);
/* For the moment, we only support PSCI 0.2 and PSCI 1.x */
if ( psci_ver != PSCI_VERSION(0, 2) && PSCI_VERSION_MAJOR(psci_ver) != 1 )
diff --git a/xen/arch/arm/smc.S b/xen/arch/arm/smc.S
deleted file mode 100644
index b8f182272a..0000000000
--- a/xen/arch/arm/smc.S
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * xen/arch/arm/smc.S
- *
- * Wrapper for Secure Monitors Calls
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- */
-
-#include <asm/macros.h>
-
-ENTRY(call_smc)
- smc #0
- ret
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 222a02dd99..8016cf306f 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -812,9 +812,6 @@ void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
void vcpu_regs_user_to_hyp(struct vcpu *vcpu,
const struct vcpu_guest_core_regs *regs);
-int call_smc(register_t function_id, register_t arg0, register_t arg1,
- register_t arg2);
-
void do_trap_hyp_serror(struct cpu_user_regs *regs);
void do_trap_guest_serror(struct cpu_user_regs *regs);
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v2 1/6] xen/arm: smccc-1.1: Make return values unsigned long
2018-09-25 17:20 ` [PATCH v2 1/6] xen/arm: smccc-1.1: Make return values unsigned long Julien Grall
@ 2018-09-25 23:18 ` Stefano Stabellini
0 siblings, 0 replies; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-25 23:18 UTC (permalink / raw)
To: Julien Grall; +Cc: Marc Zyngier, sstabellini, volodymyr_babchuk, xen-devel
On Tue, 25 Sep 2018, Julien Grall wrote:
> From: Marc Zyngier <marc.zyngier@arm.com>
>
> An unfortunate consequence of having a strong typing for the input
> values to the SMC call is that it also affects the type of the
> return values, limiting r0 to 32 bits and r{1,2,3} to whatever
> was passed as an input.
>
> Let's turn everything into "unsigned long", which satisfies the
> requirements of both architectures, and allows for the full
> range of return values.
>
> Reported-by: Stefano Stabellini <stefanos@xilinx.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> ---
> Changes in v2:
> - Add Volodymyr reviewed-by
> ---
> xen/include/asm-arm/smccc.h | 22 +++++++++++-----------
> 1 file changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
> index 74c13f8419..a31d67a1de 100644
> --- a/xen/include/asm-arm/smccc.h
> +++ b/xen/include/asm-arm/smccc.h
> @@ -119,35 +119,35 @@ struct arm_smccc_res {
>
> #define __declare_arg_0(a0, res) \
> struct arm_smccc_res *___res = res; \
> - register uin32_t r0 asm("r0") = a0; \
> + register unsigned long r0 asm("r0") = (uint32_t)a0;\
> register unsigned long r1 asm("r1"); \
> register unsigned long r2 asm("r2"); \
> register unsigned long r3 asm("r3")
>
> #define __declare_arg_1(a0, a1, res) \
> struct arm_smccc_res *___res = res; \
> - register uint32_t r0 asm("r0") = a0; \
> - register typeof(a1) r1 asm("r1") = a1; \
> + register unsigned long r0 asm("r0") = (uint32_t)a0;\
> + register unsigned long r1 asm("r1") = a1; \
> register unsigned long r2 asm("r2"); \
> register unsigned long r3 asm("r3")
>
> #define __declare_arg_2(a0, a1, a2, res) \
> struct arm_smccc_res *___res = res; \
> - register u32 r0 asm("r0") = a0; \
> - register typeof(a1) r1 asm("r1") = a1; \
> - register typeof(a2) r2 asm("r2") = a2; \
> + register unsigned long r0 asm("r0") = (uint32_t)a0;\
> + register unsigned long r1 asm("r1") = a1; \
> + register unsigned long r2 asm("r2") = a2; \
> register unsigned long r3 asm("r3")
>
> #define __declare_arg_3(a0, a1, a2, a3, res) \
> struct arm_smccc_res *___res = res; \
> - register u32 r0 asm("r0") = a0; \
> - register typeof(a1) r1 asm("r1") = a1; \
> - register typeof(a2) r2 asm("r2") = a2; \
> - register typeof(a3) r3 asm("r3") = a3
> + register unsigned long r0 asm("r0") = (uint32_t)a0;\
> + register unsigned long r1 asm("r1") = a1; \
> + register unsigned long r2 asm("r2") = a2; \
> + register unsigned long r3 asm("r3") = a3
>
> #define __declare_arg_4(a0, a1, a2, a3, a4, res) \
> __declare_arg_3(a0, a1, a2, a3, res); \
> - register typeof(a4) r4 asm("r4") = a4
> + register unsigned long r4 asm("r4") = a4
>
> #define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
> __declare_arg_4(a0, a1, a2, a3, a4, res); \
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 2/6] xen/arm: smccc-1.1: Handle function result as parameters
2018-09-25 17:20 ` [PATCH v2 2/6] xen/arm: smccc-1.1: Handle function result as parameters Julien Grall
@ 2018-09-25 23:18 ` Stefano Stabellini
0 siblings, 0 replies; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-25 23:18 UTC (permalink / raw)
To: Julien Grall; +Cc: Marc Zyngier, sstabellini, volodymyr_babchuk, xen-devel
On Tue, 25 Sep 2018, Julien Grall wrote:
> From: Marc Zyngier <marc.zyngier@arm.com>
>
> If someone has the silly idea to write something along those lines:
>
> extern u64 foo(void);
>
> void bar(struct arm_smccc_res *res)
> {
> arm_smccc_1_1_smc(0xbad, foo(), res);
> }
>
> they are in for a surprise, as this gets compiled as:
>
> 0000000000000588 <bar>:
> 588: a9be7bfd stp x29, x30, [sp, #-32]!
> 58c: 910003fd mov x29, sp
> 590: f9000bf3 str x19, [sp, #16]
> 594: aa0003f3 mov x19, x0
> 598: aa1e03e0 mov x0, x30
> 59c: 94000000 bl 0 <_mcount>
> 5a0: 94000000 bl 0 <foo>
> 5a4: aa0003e1 mov x1, x0
> 5a8: d4000003 smc #0x0
> 5ac: b4000073 cbz x19, 5b8 <bar+0x30>
> 5b0: a9000660 stp x0, x1, [x19]
> 5b4: a9010e62 stp x2, x3, [x19, #16]
> 5b8: f9400bf3 ldr x19, [sp, #16]
> 5bc: a8c27bfd ldp x29, x30, [sp], #32
> 5c0: d65f03c0 ret
> 5c4: d503201f nop
>
> The call to foo "overwrites" the x0 register for the return value,
> and we end up calling the wrong secure service.
>
> A solution is to evaluate all the parameters before assigning
> anything to specific registers, leading to the expected result:
>
> 0000000000000588 <bar>:
> 588: a9be7bfd stp x29, x30, [sp, #-32]!
> 58c: 910003fd mov x29, sp
> 590: f9000bf3 str x19, [sp, #16]
> 594: aa0003f3 mov x19, x0
> 598: aa1e03e0 mov x0, x30
> 59c: 94000000 bl 0 <_mcount>
> 5a0: 94000000 bl 0 <foo>
> 5a4: aa0003e1 mov x1, x0
> 5a8: d28175a0 mov x0, #0xbad
> 5ac: d4000003 smc #0x0
> 5b0: b4000073 cbz x19, 5bc <bar+0x34>
> 5b4: a9000660 stp x0, x1, [x19]
> 5b8: a9010e62 stp x2, x3, [x19, #16]
> 5bc: f9400bf3 ldr x19, [sp, #16]
> 5c0: a8c27bfd ldp x29, x30, [sp], #32
> 5c4: d65f03c0 ret
>
> Reported-by: Stefano Stabellini <stefanos@xilinx.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> ---
> Changes in v2:
> - Add Volodymyr's reviewed-by
> ---
> xen/include/asm-arm/smccc.h | 30 ++++++++++++++++++++----------
> 1 file changed, 20 insertions(+), 10 deletions(-)
>
> diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
> index a31d67a1de..648bef28bd 100644
> --- a/xen/include/asm-arm/smccc.h
> +++ b/xen/include/asm-arm/smccc.h
> @@ -125,41 +125,51 @@ struct arm_smccc_res {
> register unsigned long r3 asm("r3")
>
> #define __declare_arg_1(a0, a1, res) \
> + typeof(a1) __a1 = a1; \
> struct arm_smccc_res *___res = res; \
> register unsigned long r0 asm("r0") = (uint32_t)a0;\
> - register unsigned long r1 asm("r1") = a1; \
> + register unsigned long r1 asm("r1") = __a1; \
> register unsigned long r2 asm("r2"); \
> register unsigned long r3 asm("r3")
>
> #define __declare_arg_2(a0, a1, a2, res) \
> + typeof(a1) __a1 = a1; \
> + typeof(a2) __a2 = a2; \
> struct arm_smccc_res *___res = res; \
> register unsigned long r0 asm("r0") = (uint32_t)a0;\
> - register unsigned long r1 asm("r1") = a1; \
> - register unsigned long r2 asm("r2") = a2; \
> + register unsigned long r1 asm("r1") = __a1; \
> + register unsigned long r2 asm("r2") = __a2; \
> register unsigned long r3 asm("r3")
>
> #define __declare_arg_3(a0, a1, a2, a3, res) \
> + typeof(a1) __a1 = a1; \
> + typeof(a2) __a2 = a2; \
> + typeof(a3) __a3 = a3; \
> struct arm_smccc_res *___res = res; \
> register unsigned long r0 asm("r0") = (uint32_t)a0;\
> - register unsigned long r1 asm("r1") = a1; \
> - register unsigned long r2 asm("r2") = a2; \
> - register unsigned long r3 asm("r3") = a3
> + register unsigned long r1 asm("r1") = __a1; \
> + register unsigned long r2 asm("r2") = __a2; \
> + register unsigned long r3 asm("r3") = __a3
>
> #define __declare_arg_4(a0, a1, a2, a3, a4, res) \
> + typeof(a4) __a4 = a4; \
> __declare_arg_3(a0, a1, a2, a3, res); \
> - register unsigned long r4 asm("r4") = a4
> + register unsigned long r4 asm("r4") = __a4
>
> #define __declare_arg_5(a0, a1, a2, a3, a4, a5, res) \
> + typeof(a5) __a5 = a5; \
> __declare_arg_4(a0, a1, a2, a3, a4, res); \
> - register typeof(a5) r5 asm("r5") = a5
> + register typeof(a5) r5 asm("r5") = __a5
>
> #define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res) \
> + typeof(a6) __a6 = a6; \
> __declare_arg_5(a0, a1, a2, a3, a4, a5, res); \
> - register typeof(a6) r6 asm("r6") = a6
> + register typeof(a6) r6 asm("r6") = __a6
>
> #define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
> + typeof(a7) __a7 = a7; \
> __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res); \
> - register typeof(a7) r7 asm("r7") = a7
> + register typeof(a7) r7 asm("r7") = __a7
>
> #define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
> #define __declare_args(count, ...) ___declare_args(count, __VA_ARGS__)
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0
2018-09-25 17:20 ` [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0 Julien Grall
@ 2018-09-25 23:50 ` Stefano Stabellini
2018-09-26 18:45 ` Julien Grall
0 siblings, 1 reply; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-25 23:50 UTC (permalink / raw)
To: Julien Grall; +Cc: Edgar E. Iglesias, sstabellini, volodymyr_babchuk, xen-devel
On Tue, 25 Sep 2018, Julien Grall wrote:
> From: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>
> Existing SMC wrapper call_smc() allows only 4 parameters and
> returns only one value. This is enough for existing
> use in PSCI code, but TEE mediator will need a call that is
> fully compatible with ARM SMCCC v1.0.
>
> This patch adds a wrapper for both arm32 and arm64. In the case of
> arm32, the wrapper is just an alias to the ARM SMCCC v1.1 as the
> convention is the same.
>
> CC: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
> [julien: Rework the wrapper to make it closer to SMCC 1.1 wrapper]
> Signed-off-by: Julien Grall <julien.grall@arm.com>
I have been struggling to find the old doc for SMCCC v1.0, all the
references have been updated to v1.1 online now. Do you have a link?
> ---
> xen/arch/arm/arm64/Makefile | 1 +
> xen/arch/arm/arm64/asm-offsets.c | 5 ++++
> xen/arch/arm/arm64/smc.S | 32 +++++++++++++++++++++++++
> xen/include/asm-arm/smccc.h | 51 +++++++++++++++++++++++++++++++++++++++-
> 4 files changed, 88 insertions(+), 1 deletion(-)
> create mode 100644 xen/arch/arm/arm64/smc.S
>
> diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
> index bb5c610b2a..c4f3a28a0d 100644
> --- a/xen/arch/arm/arm64/Makefile
> +++ b/xen/arch/arm/arm64/Makefile
> @@ -8,6 +8,7 @@ obj-y += domain.o
> obj-y += entry.o
> obj-y += insn.o
> obj-$(CONFIG_LIVEPATCH) += livepatch.o
> +obj-y += smc.o
> obj-y += smpboot.o
> obj-y += traps.o
> obj-y += vfp.o
> diff --git a/xen/arch/arm/arm64/asm-offsets.c b/xen/arch/arm/arm64/asm-offsets.c
> index 62833d8c8b..280ddb55bf 100644
> --- a/xen/arch/arm/arm64/asm-offsets.c
> +++ b/xen/arch/arm/arm64/asm-offsets.c
> @@ -10,6 +10,7 @@
> #include <xen/bitops.h>
> #include <public/xen.h>
> #include <asm/current.h>
> +#include <asm/smccc.h>
>
> #define DEFINE(_sym, _val) \
> asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \
> @@ -51,6 +52,10 @@ void __dummy__(void)
>
> BLANK();
> OFFSET(INITINFO_stack, struct init_info, stack);
> +
> + BLANK();
> + OFFSET(SMCCC_RES_a0, struct arm_smccc_res, a0);
> + OFFSET(SMCCC_RES_a2, struct arm_smccc_res, a2);
> }
>
> /*
> diff --git a/xen/arch/arm/arm64/smc.S b/xen/arch/arm/arm64/smc.S
> new file mode 100644
> index 0000000000..b0752be57e
> --- /dev/null
> +++ b/xen/arch/arm/arm64/smc.S
> @@ -0,0 +1,32 @@
> +/*
> + * xen/arch/arm/arm64/smc.S
> + *
> + * Wrapper for Secure Monitors Calls
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License.
> + *
> + * 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.
> + */
> +
> +#include <asm/asm_defns.h>
> +#include <asm/macros.h>
> +
> +/*
> + * void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
> + * register_t a3, register_t a4, register_t a5,
> + * register_t a6, register_t a7,
> + * struct arm_smccc_res *res)
> + */
> +ENTRY(__arm_smccc_1_0_smc)
> + smc #0
> + ldr x4, [sp]
> + cbz x4, 1f /* No need to store the result */
> + stp x0, x1, [x4, #SMCCC_RES_a0]
> + stp x2, x3, [x4, #SMCCC_RES_a2]
> +1:
> + ret
As I mentioned, I couldn't find the doc, but it looks like the Linux
implementation always copies back the results
(arch/arm64/kernel/smccc-call.S)? Shouldn't we zero x0-x3 at least?
Other than that, it looks fine.
> diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
> index 648bef28bd..1ed6cbaa48 100644
> --- a/xen/include/asm-arm/smccc.h
> +++ b/xen/include/asm-arm/smccc.h
> @@ -207,7 +207,56 @@ struct arm_smccc_res {
> *___res = (typeof(*___res)){r0, r1, r2, r3}; \
> } while ( 0 )
>
> -#endif
> +/*
> + * The calling convention for arm32 is the same for both SMCCC v1.0 and
> + * v1.1.
> + */
> +#ifdef CONFIG_ARM_32
> +#define arm_smccc_1_0_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
> +#else
> +
> +void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
> + register_t a3, register_t a4, register_t a5,
> + register_t a6, register_t a7,
> + struct arm_smccc_res *res);
> +
> +/* Macros to handle variadic parameter for SMCCC v1.0 helper */
> +#define __arm_smccc_1_0_smc_7(a0, a1, a2, a3, a4, a5, a6, a7, res) \
> + __arm_smccc_1_0_smc(a0, a1, a2, a3, a4, a5, a6, a7, res)
> +
> +#define __arm_smccc_1_0_smc_6(a0, a1, a2, a3, a4, a5, a6, res) \
> + __arm_smccc_1_0_smc_7(a0, a1, a2, a3, a4, a5, a6, 0, res)
> +
> +#define __arm_smccc_1_0_smc_5(a0, a1, a2, a3, a4, a5, res) \
> + __arm_smccc_1_0_smc_6(a0, a1, a2, a3, a4, a5, 0, res)
> +
> +#define __arm_smccc_1_0_smc_4(a0, a1, a2, a3, a4, res) \
> + __arm_smccc_1_0_smc_5(a0, a1, a2, a3, a4, 0, res)
> +
> +#define __arm_smccc_1_0_smc_3(a0, a1, a2, a3, res) \
> + __arm_smccc_1_0_smc_4(a0, a1, a2, a3, 0, res)
> +
> +#define __arm_smccc_1_0_smc_2(a0, a1, a2, res) \
> + __arm_smccc_1_0_smc_3(a0, a1, a2, 0, res)
> +
> +#define __arm_smccc_1_0_smc_1(a0, a1, res) \
> + __arm_smccc_1_0_smc_2(a0, a1, 0, res)
> +
> +#define __arm_smccc_1_0_smc_0(a0, res) \
> + __arm_smccc_1_0_smc_1(a0, 0, res)
> +
> +#define ___arm_smccc_1_0_smc_count(count, ...) \
> + __arm_smccc_1_0_smc_ ## count(__VA_ARGS__)
> +
> +#define __arm_smccc_1_0_smc_count(count, ...) \
> + ___arm_smccc_1_0_smc_count(count, __VA_ARGS__)
> +
> +#define arm_smccc_1_0_smc(...) \
> + __arm_smccc_1_0_smc_count(__count_args(__VA_ARGS__), __VA_ARGS__)
> +
> +#endif /* CONFIG_ARM_64 */
> +
> +#endif /* __ASSEMBLY__ */
>
> /*
> * Construct function identifier from call type (fast or standard),
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention
2018-09-25 17:20 ` [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention Julien Grall
@ 2018-09-25 23:52 ` Stefano Stabellini
2018-09-26 11:24 ` Volodymyr Babchuk
1 sibling, 0 replies; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-25 23:52 UTC (permalink / raw)
To: Julien Grall; +Cc: sstabellini, volodymyr_babchuk, xen-devel
On Tue, 25 Sep 2018, Julien Grall wrote:
> Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> ---
> Changes in v2:
> - Invert the condition
> - Add missing includes
> ---
> xen/arch/arm/psci.c | 4 ++++
> xen/include/asm-arm/cpufeature.h | 3 ++-
> xen/include/asm-arm/smccc.h | 11 +++++++++++
> 3 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> index 3cf5ecf0f3..941eec921b 100644
> --- a/xen/arch/arm/psci.c
> +++ b/xen/arch/arm/psci.c
> @@ -21,6 +21,7 @@
> #include <xen/types.h>
> #include <xen/mm.h>
> #include <xen/smp.h>
> +#include <asm/cpufeature.h>
> #include <asm/psci.h>
> #include <asm/acpi.h>
>
> @@ -118,6 +119,9 @@ static void __init psci_init_smccc(void)
> smccc_ver = ret;
> }
>
> + if ( smccc_ver >= SMCCC_VERSION(1, 1) )
> + cpus_set_cap(ARM_SMCCC_1_1);
> +
> printk(XENLOG_INFO "Using SMC Calling Convention v%u.%u\n",
> SMCCC_VERSION_MAJOR(smccc_ver), SMCCC_VERSION_MINOR(smccc_ver));
> }
> diff --git a/xen/include/asm-arm/cpufeature.h b/xen/include/asm-arm/cpufeature.h
> index c6cbc2ec84..2d82264427 100644
> --- a/xen/include/asm-arm/cpufeature.h
> +++ b/xen/include/asm-arm/cpufeature.h
> @@ -44,8 +44,9 @@
> #define SKIP_CTXT_SWITCH_SERROR_SYNC 6
> #define ARM_HARDEN_BRANCH_PREDICTOR 7
> #define ARM_SSBD 8
> +#define ARM_SMCCC_1_1 9
>
> -#define ARM_NCAPS 9
> +#define ARM_NCAPS 10
>
> #ifndef __ASSEMBLY__
>
> diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
> index 1ed6cbaa48..126399dd70 100644
> --- a/xen/include/asm-arm/smccc.h
> +++ b/xen/include/asm-arm/smccc.h
> @@ -16,6 +16,9 @@
> #ifndef __ASM_ARM_SMCCC_H__
> #define __ASM_ARM_SMCCC_H__
>
> +#include <asm/alternative.h>
> +#include <asm/cpufeature.h>
> +
> #define SMCCC_VERSION_MAJOR_SHIFT 16
> #define SMCCC_VERSION_MINOR_MASK \
> ((1U << SMCCC_VERSION_MAJOR_SHIFT) - 1)
> @@ -213,6 +216,7 @@ struct arm_smccc_res {
> */
> #ifdef CONFIG_ARM_32
> #define arm_smccc_1_0_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
> +#define arm_smccc_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
> #else
>
> void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
> @@ -254,6 +258,13 @@ void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
> #define arm_smccc_1_0_smc(...) \
> __arm_smccc_1_0_smc_count(__count_args(__VA_ARGS__), __VA_ARGS__)
>
> +#define arm_smccc_smc(...) \
> + do { \
> + if ( cpus_have_const_cap(ARM_SMCCC_1_1) ) \
> + arm_smccc_1_1_smc(__VA_ARGS__); \
> + else \
> + arm_smccc_1_0_smc(__VA_ARGS__); \
> + } while ( 0 )
> #endif /* CONFIG_ARM_64 */
>
> #endif /* __ASSEMBLY__ */
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc
2018-09-25 17:20 ` [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc Julien Grall
@ 2018-09-25 23:57 ` Stefano Stabellini
2018-09-26 19:04 ` Julien Grall
0 siblings, 1 reply; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-25 23:57 UTC (permalink / raw)
To: Julien Grall; +Cc: sstabellini, volodymyr_babchuk, xen-devel
On Tue, 25 Sep 2018, Julien Grall wrote:
> call_smc is a subset of arm_smccc_smc. Rather than having 2 methods to
> do SMCCC call, replace all call to the former by the later.
>
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> ---
> xen/arch/arm/Makefile | 1 -
> xen/arch/arm/platforms/exynos5.c | 3 ++-
> xen/arch/arm/platforms/seattle.c | 4 ++--
> xen/arch/arm/psci.c | 37 +++++++++++++++++++++++++------------
> xen/arch/arm/smc.S | 21 ---------------------
> xen/include/asm-arm/processor.h | 3 ---
> 6 files changed, 29 insertions(+), 40 deletions(-)
> delete mode 100644 xen/arch/arm/smc.S
>
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index b9b141dc84..37fa8268b3 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -39,7 +39,6 @@ obj-y += processor.o
> obj-y += psci.o
> obj-y += setup.o
> obj-y += shutdown.o
> -obj-y += smc.o
> obj-y += smp.o
> obj-y += smpboot.o
> obj-y += sysctl.o
> diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
> index c15ecf80f5..e2c0b7b878 100644
> --- a/xen/arch/arm/platforms/exynos5.c
> +++ b/xen/arch/arm/platforms/exynos5.c
> @@ -26,6 +26,7 @@
> #include <asm/platforms/exynos5.h>
> #include <asm/platform.h>
> #include <asm/io.h>
> +#include <asm/smccc.h>
>
> static bool secure_firmware;
>
> @@ -249,7 +250,7 @@ static int exynos5_cpu_up(int cpu)
> iounmap(power);
>
> if ( secure_firmware )
> - call_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
> + arm_smccc_smc(SMC_CMD_CPU1BOOT, cpu, NULL);
>
> return cpu_up_send_sgi(cpu);
> }
> diff --git a/xen/arch/arm/platforms/seattle.c b/xen/arch/arm/platforms/seattle.c
> index 893cc17972..64cc1868c2 100644
> --- a/xen/arch/arm/platforms/seattle.c
> +++ b/xen/arch/arm/platforms/seattle.c
> @@ -33,12 +33,12 @@ static const char * const seattle_dt_compat[] __initconst =
> */
> static void seattle_system_reset(void)
> {
> - call_smc(PSCI_0_2_FN32_SYSTEM_RESET, 0, 0, 0);
> + arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_RESET, NULL);
> }
>
> static void seattle_system_off(void)
> {
> - call_smc(PSCI_0_2_FN32_SYSTEM_OFF, 0, 0, 0);
> + arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_OFF, NULL);
> }
>
> PLATFORM_START(seattle, "SEATTLE")
> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> index 941eec921b..02737e6caa 100644
> --- a/xen/arch/arm/psci.c
> +++ b/xen/arch/arm/psci.c
> @@ -42,42 +42,53 @@ uint32_t smccc_ver;
>
> static uint32_t psci_cpu_on_nr;
>
> +#define PSCI_RET(res) ((int32_t)(res).a0)
> +
> int call_psci_cpu_on(int cpu)
> {
> - return call_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(init_secondary), 0);
> + struct arm_smccc_res res;
> +
> + arm_smccc_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(init_secondary),
> + &res);
> +
> + return (int32_t)res.a0;
> }
Can't we use PSCI_RET(res) here?
Also in general, should we care about the type mismatch int32_t vs. int
which is the return type of this function?
> void call_psci_cpu_off(void)
> {
> if ( psci_ver > PSCI_VERSION(0, 1) )
> {
> - int errno;
> + struct arm_smccc_res res;
>
> /* If successfull the PSCI cpu_off call doesn't return */
> - errno = call_smc(PSCI_0_2_FN32_CPU_OFF, 0, 0, 0);
> + arm_smccc_smc(PSCI_0_2_FN32_CPU_OFF, &res);
> panic("PSCI cpu off failed for CPU%d err=%d\n", smp_processor_id(),
> - errno);
> + PSCI_RET(res));
> }
> }
>
> void call_psci_system_off(void)
> {
> if ( psci_ver > PSCI_VERSION(0, 1) )
> - call_smc(PSCI_0_2_FN32_SYSTEM_OFF, 0, 0, 0);
> + arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_OFF, NULL);
> }
>
> void call_psci_system_reset(void)
> {
> if ( psci_ver > PSCI_VERSION(0, 1) )
> - call_smc(PSCI_0_2_FN32_SYSTEM_RESET, 0, 0, 0);
> + arm_smccc_smc(PSCI_0_2_FN32_SYSTEM_RESET, NULL);
> }
>
> static int __init psci_features(uint32_t psci_func_id)
> {
> + struct arm_smccc_res res;
> +
> if ( psci_ver < PSCI_VERSION(1, 0) )
> return PSCI_NOT_SUPPORTED;
>
> - return call_smc(PSCI_1_0_FN32_PSCI_FEATURES, psci_func_id, 0, 0);
> + arm_smccc_smc(PSCI_1_0_FN32_PSCI_FEATURES, psci_func_id, NULL);
> +
> + return PSCI_RET(res);
> }
>
> static int __init psci_is_smc_method(const struct dt_device_node *psci)
> @@ -112,11 +123,11 @@ static void __init psci_init_smccc(void)
>
> if ( psci_features(ARM_SMCCC_VERSION_FID) != PSCI_NOT_SUPPORTED )
> {
> - uint32_t ret;
> + struct arm_smccc_res res;
>
> - ret = call_smc(ARM_SMCCC_VERSION_FID, 0, 0, 0);
> - if ( ret != ARM_SMCCC_NOT_SUPPORTED )
> - smccc_ver = ret;
> + arm_smccc_smc(ARM_SMCCC_VERSION_FID, &res);
> + if ( PSCI_RET(res) != ARM_SMCCC_NOT_SUPPORTED )
> + smccc_ver = PSCI_RET(res);
> }
>
> if ( smccc_ver >= SMCCC_VERSION(1, 1) )
> @@ -165,6 +176,7 @@ static int __init psci_init_0_2(void)
> { /* sentinel */ },
> };
> int ret;
> + struct arm_smccc_res res;
>
> if ( acpi_disabled )
> {
> @@ -186,7 +198,8 @@ static int __init psci_init_0_2(void)
> }
> }
>
> - psci_ver = call_smc(PSCI_0_2_FN32_PSCI_VERSION, 0, 0, 0);
> + arm_smccc_smc(PSCI_0_2_FN32_PSCI_VERSION, &res);
> + psci_ver = PSCI_RET(res);
>
> /* For the moment, we only support PSCI 0.2 and PSCI 1.x */
> if ( psci_ver != PSCI_VERSION(0, 2) && PSCI_VERSION_MAJOR(psci_ver) != 1 )
> diff --git a/xen/arch/arm/smc.S b/xen/arch/arm/smc.S
> deleted file mode 100644
> index b8f182272a..0000000000
> --- a/xen/arch/arm/smc.S
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -/*
> - * xen/arch/arm/smc.S
> - *
> - * Wrapper for Secure Monitors Calls
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> - * 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.
> - */
> -
> -#include <asm/macros.h>
> -
> -ENTRY(call_smc)
> - smc #0
> - ret
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 222a02dd99..8016cf306f 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -812,9 +812,6 @@ void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
> void vcpu_regs_user_to_hyp(struct vcpu *vcpu,
> const struct vcpu_guest_core_regs *regs);
>
> -int call_smc(register_t function_id, register_t arg0, register_t arg1,
> - register_t arg2);
> -
> void do_trap_hyp_serror(struct cpu_user_regs *regs);
>
> void do_trap_guest_serror(struct cpu_user_regs *regs);
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention
2018-09-25 17:20 ` [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention Julien Grall
2018-09-25 23:52 ` Stefano Stabellini
@ 2018-09-26 11:24 ` Volodymyr Babchuk
1 sibling, 0 replies; 23+ messages in thread
From: Volodymyr Babchuk @ 2018-09-26 11:24 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: sstabellini
Hi Julien,
On 25.09.18 20:20, Julien Grall wrote:
> Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>
> ---
> Changes in v2:
> - Invert the condition
> - Add missing includes
> ---
> xen/arch/arm/psci.c | 4 ++++
> xen/include/asm-arm/cpufeature.h | 3 ++-
> xen/include/asm-arm/smccc.h | 11 +++++++++++
> 3 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> index 3cf5ecf0f3..941eec921b 100644
> --- a/xen/arch/arm/psci.c
> +++ b/xen/arch/arm/psci.c
> @@ -21,6 +21,7 @@
> #include <xen/types.h>
> #include <xen/mm.h>
> #include <xen/smp.h>
> +#include <asm/cpufeature.h>
> #include <asm/psci.h>
> #include <asm/acpi.h>
>
> @@ -118,6 +119,9 @@ static void __init psci_init_smccc(void)
> smccc_ver = ret;
> }
>
> + if ( smccc_ver >= SMCCC_VERSION(1, 1) )
> + cpus_set_cap(ARM_SMCCC_1_1);
> +
> printk(XENLOG_INFO "Using SMC Calling Convention v%u.%u\n",
> SMCCC_VERSION_MAJOR(smccc_ver), SMCCC_VERSION_MINOR(smccc_ver));
> }
> diff --git a/xen/include/asm-arm/cpufeature.h b/xen/include/asm-arm/cpufeature.h
> index c6cbc2ec84..2d82264427 100644
> --- a/xen/include/asm-arm/cpufeature.h
> +++ b/xen/include/asm-arm/cpufeature.h
> @@ -44,8 +44,9 @@
> #define SKIP_CTXT_SWITCH_SERROR_SYNC 6
> #define ARM_HARDEN_BRANCH_PREDICTOR 7
> #define ARM_SSBD 8
> +#define ARM_SMCCC_1_1 9
>
> -#define ARM_NCAPS 9
> +#define ARM_NCAPS 10
>
> #ifndef __ASSEMBLY__
>
> diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
> index 1ed6cbaa48..126399dd70 100644
> --- a/xen/include/asm-arm/smccc.h
> +++ b/xen/include/asm-arm/smccc.h
> @@ -16,6 +16,9 @@
> #ifndef __ASM_ARM_SMCCC_H__
> #define __ASM_ARM_SMCCC_H__
>
> +#include <asm/alternative.h>
> +#include <asm/cpufeature.h>
> +
> #define SMCCC_VERSION_MAJOR_SHIFT 16
> #define SMCCC_VERSION_MINOR_MASK \
> ((1U << SMCCC_VERSION_MAJOR_SHIFT) - 1)
> @@ -213,6 +216,7 @@ struct arm_smccc_res {
> */
> #ifdef CONFIG_ARM_32
> #define arm_smccc_1_0_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
> +#define arm_smccc_smc(...) arm_smccc_1_1_smc(__VA_ARGS__)
> #else
>
> void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
> @@ -254,6 +258,13 @@ void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
> #define arm_smccc_1_0_smc(...) \
> __arm_smccc_1_0_smc_count(__count_args(__VA_ARGS__), __VA_ARGS__)
>
> +#define arm_smccc_smc(...) \
> + do { \
> + if ( cpus_have_const_cap(ARM_SMCCC_1_1) ) \
> + arm_smccc_1_1_smc(__VA_ARGS__); \
> + else \
> + arm_smccc_1_0_smc(__VA_ARGS__); \
> + } while ( 0 )
> #endif /* CONFIG_ARM_64 */
>
> #endif /* __ASSEMBLY__ */
>
--
Volodymyr Babchuk
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps
2018-09-25 17:20 ` [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps Julien Grall
@ 2018-09-26 16:53 ` Stefano Stabellini
2018-09-26 19:00 ` Julien Grall
0 siblings, 1 reply; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-26 16:53 UTC (permalink / raw)
To: Julien Grall; +Cc: sstabellini, volodymyr_babchuk, xen-devel
On Tue, 25 Sep 2018, Julien Grall wrote:
> Some capababilities are set right during boot and will never change
> afterwards. At the moment, the function cpu_have_caps will check whether
> the cap is enabled from the memory.
>
> It is possible to avoid the load from the memory by using an
> ALTERNATIVE. With that the check is just reduced to 1 instruction.
>
> Signed-off-by: Julien Grall <julien.grall@arm.com>
I enjoyed reading the patch :-) But I don't think it is worth going
into this extreme level of optimization. test_bit is efficient enough,
right? What do you think we need to use alternatives just to check one
bit?
> ---
>
> This is the static key for the poor. At some point we might want to
> introduce something similar to static key in Xen.
>
> Changes in v2:
> - Use unlikely
> ---
> xen/include/asm-arm/cpufeature.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/xen/include/asm-arm/cpufeature.h b/xen/include/asm-arm/cpufeature.h
> index 3de6b54301..c6cbc2ec84 100644
> --- a/xen/include/asm-arm/cpufeature.h
> +++ b/xen/include/asm-arm/cpufeature.h
> @@ -63,6 +63,18 @@ static inline bool cpus_have_cap(unsigned int num)
> return test_bit(num, cpu_hwcaps);
> }
>
> +/* System capability check for constant cap */
> +#define cpus_have_const_cap(num) ({ \
> + bool __ret; \
> + \
> + asm volatile (ALTERNATIVE("mov %0, #0", \
> + "mov %0, #1", \
> + num) \
> + : "=r" (__ret)); \
> + \
> + unlikely(__ret); \
> + })
> +
> static inline void cpus_set_cap(unsigned int num)
> {
> if (num >= ARM_NCAPS)
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0
2018-09-25 23:50 ` Stefano Stabellini
@ 2018-09-26 18:45 ` Julien Grall
2018-09-27 23:02 ` Stefano Stabellini
0 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-26 18:45 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Edgar E. Iglesias, volodymyr_babchuk, xen-devel
Hi Stefano,
On 09/26/2018 12:50 AM, Stefano Stabellini wrote:
> On Tue, 25 Sep 2018, Julien Grall wrote:
>> From: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>>
>> Existing SMC wrapper call_smc() allows only 4 parameters and
>> returns only one value. This is enough for existing
>> use in PSCI code, but TEE mediator will need a call that is
>> fully compatible with ARM SMCCC v1.0.
>>
>> This patch adds a wrapper for both arm32 and arm64. In the case of
>> arm32, the wrapper is just an alias to the ARM SMCCC v1.1 as the
>> convention is the same.
>>
>> CC: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
>> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>> [julien: Rework the wrapper to make it closer to SMCC 1.1 wrapper]
>> Signed-off-by: Julien Grall <julien.grall@arm.com>
>
> I have been struggling to find the old doc for SMCCC v1.0, all the
> references have been updated to v1.1 online now. Do you have a link?
Are you sure? All the references are still to v1.0 (DEN 0028B). See [1].
>> diff --git a/xen/arch/arm/arm64/smc.S b/xen/arch/arm/arm64/smc.S
>> new file mode 100644
>> index 0000000000..b0752be57e
>> --- /dev/null
>> +++ b/xen/arch/arm/arm64/smc.S
>> @@ -0,0 +1,32 @@
>> +/*
>> + * xen/arch/arm/arm64/smc.S
>> + *
>> + * Wrapper for Secure Monitors Calls
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License.
>> + *
>> + * 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.
>> + */
>> +
>> +#include <asm/asm_defns.h>
>> +#include <asm/macros.h>
>> +
>> +/*
>> + * void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
>> + * register_t a3, register_t a4, register_t a5,
>> + * register_t a6, register_t a7,
>> + * struct arm_smccc_res *res)
>> + */
>> +ENTRY(__arm_smccc_1_0_smc)
>> + smc #0
>> + ldr x4, [sp]
>> + cbz x4, 1f /* No need to store the result */
>> + stp x0, x1, [x4, #SMCCC_RES_a0]
>> + stp x2, x3, [x4, #SMCCC_RES_a2]
>> +1:
>> + ret
>
> As I mentioned, I couldn't find the doc, but it looks like the Linux
> implementation always copies back the results
> (arch/arm64/kernel/smccc-call.S)? Shouldn't we zero x0-x3 at least?
Could you provide more details on what looks wrong?
The results are copied in the array res using stp instructions. The only
difference with Linux implementation is we don't handle quirk.
Cheers,
[1]
https://developer.arm.com/products/architecture/cpu-architecture/a-profile/docs/den0028/latest/smc-calling-convention-system-software-on-arm-platforms
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps
2018-09-26 16:53 ` Stefano Stabellini
@ 2018-09-26 19:00 ` Julien Grall
2018-09-27 22:34 ` Stefano Stabellini
0 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-26 19:00 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: volodymyr_babchuk, xen-devel
Hi Stefano,
On 09/26/2018 05:53 PM, Stefano Stabellini wrote:
> On Tue, 25 Sep 2018, Julien Grall wrote:
>> Some capababilities are set right during boot and will never change
>> afterwards. At the moment, the function cpu_have_caps will check whether
>> the cap is enabled from the memory.
>>
>> It is possible to avoid the load from the memory by using an
>> ALTERNATIVE. With that the check is just reduced to 1 instruction.
>>
>> Signed-off-by: Julien Grall <julien.grall@arm.com>
>
> I enjoyed reading the patch :-) But I don't think it is worth going
> into this extreme level of optimization. test_bit is efficient enough,
> right? What do you think we need to use alternatives just to check one
> bit?
We already have an helper using test_bit (see cpus_have_cap). However
test_bit requires to load the word from the memory. This is an overhead
when the decision never change after boot.
One load may be insignificant by itself (thought may have a cache miss),
but if you are in hotpath this is a win in long term.
The mechanism is very similar to static key but for the poor (I don't
have much time to implement better for now). We already use similar
construction on other places (see CHECK_WORKAROUND_HELPER).
Cheers,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc
2018-09-25 23:57 ` Stefano Stabellini
@ 2018-09-26 19:04 ` Julien Grall
2018-09-27 22:41 ` Stefano Stabellini
0 siblings, 1 reply; 23+ messages in thread
From: Julien Grall @ 2018-09-26 19:04 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: volodymyr_babchuk, xen-devel
Hi Stefano,
On 09/26/2018 12:57 AM, Stefano Stabellini wrote:
> On Tue, 25 Sep 2018, Julien Grall wrote:
>> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
>> index 941eec921b..02737e6caa 100644
>> --- a/xen/arch/arm/psci.c
>> +++ b/xen/arch/arm/psci.c
>> @@ -42,42 +42,53 @@ uint32_t smccc_ver;
>>
>> static uint32_t psci_cpu_on_nr;
>>
>> +#define PSCI_RET(res) ((int32_t)(res).a0)
>> +
>> int call_psci_cpu_on(int cpu)
>> {
>> - return call_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(init_secondary), 0);
>> + struct arm_smccc_res res;
>> +
>> + arm_smccc_smc(psci_cpu_on_nr, cpu_logical_map(cpu), __pa(init_secondary),
>> + &res);
>> +
>> + return (int32_t)res.a0;
>> }
>
> Can't we use PSCI_RET(res) here?
I missed that one. I will update it.
>
> Also in general, should we care about the type mismatch int32_t vs. int
> which is the return type of this function?
The only issue I could see is if sizeof(int) < sizeof(int32_t). If that
happen, then psci.c would be our least concern as we always assume int
would at least 32-bit wide.
I would prefer to keep the return of the function int and casting the
result with (int32_t). The latter is helpful to know what is the size of
the result (a0 is 64-bit).
Cheers,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps
2018-09-26 19:00 ` Julien Grall
@ 2018-09-27 22:34 ` Stefano Stabellini
2018-09-28 9:27 ` Julien Grall
0 siblings, 1 reply; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-27 22:34 UTC (permalink / raw)
To: Julien Grall; +Cc: Stefano Stabellini, volodymyr_babchuk, xen-devel
On Wed, 26 Sep 2018, Julien Grall wrote:
> Hi Stefano,
>
> On 09/26/2018 05:53 PM, Stefano Stabellini wrote:
> > On Tue, 25 Sep 2018, Julien Grall wrote:
> > > Some capababilities are set right during boot and will never change
> > > afterwards. At the moment, the function cpu_have_caps will check whether
> > > the cap is enabled from the memory.
> > >
> > > It is possible to avoid the load from the memory by using an
> > > ALTERNATIVE. With that the check is just reduced to 1 instruction.
> > >
> > > Signed-off-by: Julien Grall <julien.grall@arm.com>
> >
> > I enjoyed reading the patch :-) But I don't think it is worth going
> > into this extreme level of optimization. test_bit is efficient enough,
> > right? What do you think we need to use alternatives just to check one
> > bit?
>
> We already have an helper using test_bit (see cpus_have_cap). However test_bit
> requires to load the word from the memory. This is an overhead when the
> decision never change after boot.
>
> One load may be insignificant by itself (thought may have a cache miss), but
> if you are in hotpath this is a win in long term.
>
> The mechanism is very similar to static key but for the poor (I don't have
> much time to implement better for now). We already use similar construction on
> other places (see CHECK_WORKAROUND_HELPER).
I like the mechanism and the little ALTERNATIVE trick. I can see it
could very useful in some cases. It is just that it is a bit of a waste
to use it on SMCCC virtualization -- SMCCC calls cannot be done often
enough for this to make a difference.
But who am I to complain when you make things faster? :-)
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc
2018-09-26 19:04 ` Julien Grall
@ 2018-09-27 22:41 ` Stefano Stabellini
2018-10-01 10:01 ` Julien Grall
0 siblings, 1 reply; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-27 22:41 UTC (permalink / raw)
To: Julien Grall; +Cc: Stefano Stabellini, volodymyr_babchuk, xen-devel
On Wed, 26 Sep 2018, Julien Grall wrote:
> Hi Stefano,
>
> On 09/26/2018 12:57 AM, Stefano Stabellini wrote:
> > On Tue, 25 Sep 2018, Julien Grall wrote:
> > > diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> > > index 941eec921b..02737e6caa 100644
> > > --- a/xen/arch/arm/psci.c
> > > +++ b/xen/arch/arm/psci.c
> > > @@ -42,42 +42,53 @@ uint32_t smccc_ver;
> > > static uint32_t psci_cpu_on_nr;
> > > +#define PSCI_RET(res) ((int32_t)(res).a0)
> > > +
> > > int call_psci_cpu_on(int cpu)
> > > {
> > > - return call_smc(psci_cpu_on_nr, cpu_logical_map(cpu),
> > > __pa(init_secondary), 0);
> > > + struct arm_smccc_res res;
> > > +
> > > + arm_smccc_smc(psci_cpu_on_nr, cpu_logical_map(cpu),
> > > __pa(init_secondary),
> > > + &res);
> > > +
> > > + return (int32_t)res.a0;
> > > }
> >
> > Can't we use PSCI_RET(res) here?
>
> I missed that one. I will update it.
>
> >
> > Also in general, should we care about the type mismatch int32_t vs. int
> > which is the return type of this function?
>
> The only issue I could see is if sizeof(int) < sizeof(int32_t). If that
> happen, then psci.c would be our least concern as we always assume int would
> at least 32-bit wide.
>
> I would prefer to keep the return of the function int and casting the result
> with (int32_t). The latter is helpful to know what is the size of the result
> (a0 is 64-bit).
It is a good idea to keep the cast. I don't have a strong opinion on
whether the functions should return int or int32_t. The only question is
whether we want to cast to (int32_t) or to (int). I would prefer to cast
to the same type of the return of the function. So if we keep int as
return type, then casting to (int). However, given that in practice it
makes no difference, I can ack the patch in any case.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0
2018-09-26 18:45 ` Julien Grall
@ 2018-09-27 23:02 ` Stefano Stabellini
2018-09-28 9:20 ` Julien Grall
0 siblings, 1 reply; 23+ messages in thread
From: Stefano Stabellini @ 2018-09-27 23:02 UTC (permalink / raw)
To: Julien Grall
Cc: Edgar E. Iglesias, Stefano Stabellini, volodymyr_babchuk, xen-devel
On Wed, 26 Sep 2018, Julien Grall wrote:
> Hi Stefano,
>
> On 09/26/2018 12:50 AM, Stefano Stabellini wrote:
> > On Tue, 25 Sep 2018, Julien Grall wrote:
> > > From: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
> > >
> > > Existing SMC wrapper call_smc() allows only 4 parameters and
> > > returns only one value. This is enough for existing
> > > use in PSCI code, but TEE mediator will need a call that is
> > > fully compatible with ARM SMCCC v1.0.
> > >
> > > This patch adds a wrapper for both arm32 and arm64. In the case of
> > > arm32, the wrapper is just an alias to the ARM SMCCC v1.1 as the
> > > convention is the same.
> > >
> > > CC: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> > > Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
> > > [julien: Rework the wrapper to make it closer to SMCC 1.1 wrapper]
> > > Signed-off-by: Julien Grall <julien.grall@arm.com>
> >
> > I have been struggling to find the old doc for SMCCC v1.0, all the
> > references have been updated to v1.1 online now. Do you have a link?
>
> Are you sure? All the references are still to v1.0 (DEN 0028B). See [1].
The lack of version in the doc confused me.
> > > diff --git a/xen/arch/arm/arm64/smc.S b/xen/arch/arm/arm64/smc.S
> > > new file mode 100644
> > > index 0000000000..b0752be57e
> > > --- /dev/null
> > > +++ b/xen/arch/arm/arm64/smc.S
> > > @@ -0,0 +1,32 @@
> > > +/*
> > > + * xen/arch/arm/arm64/smc.S
> > > + *
> > > + * Wrapper for Secure Monitors Calls
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License as published by
> > > + * the Free Software Foundation; either version 2 of the License.
> > > + *
> > > + * 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.
> > > + */
> > > +
> > > +#include <asm/asm_defns.h>
> > > +#include <asm/macros.h>
> > > +
> > > +/*
> > > + * void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
> > > + * register_t a3, register_t a4, register_t a5,
> > > + * register_t a6, register_t a7,
> > > + * struct arm_smccc_res *res)
> > > + */
> > > +ENTRY(__arm_smccc_1_0_smc)
> > > + smc #0
> > > + ldr x4, [sp]
> > > + cbz x4, 1f /* No need to store the result */
> > > + stp x0, x1, [x4, #SMCCC_RES_a0]
> > > + stp x2, x3, [x4, #SMCCC_RES_a2]
> > > +1:
> > > + ret
> >
> > As I mentioned, I couldn't find the doc, but it looks like the Linux
> > implementation always copies back the results
> > (arch/arm64/kernel/smccc-call.S)? Shouldn't we zero x0-x3 at least?
> Could you provide more details on what looks wrong?
>
> The results are copied in the array res using stp instructions. The only
> difference with Linux implementation is we don't handle quirk.
The only difference is that in this implementation we handle `res' being
NULL, which I think is a good idea:
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0
2018-09-27 23:02 ` Stefano Stabellini
@ 2018-09-28 9:20 ` Julien Grall
0 siblings, 0 replies; 23+ messages in thread
From: Julien Grall @ 2018-09-28 9:20 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Edgar E. Iglesias, volodymyr_babchuk, xen-devel
Hi Stefano,
On 09/28/2018 12:02 AM, Stefano Stabellini wrote:
> On Wed, 26 Sep 2018, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 09/26/2018 12:50 AM, Stefano Stabellini wrote:
>>> On Tue, 25 Sep 2018, Julien Grall wrote:
>>>> From: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>>>>
>>>> Existing SMC wrapper call_smc() allows only 4 parameters and
>>>> returns only one value. This is enough for existing
>>>> use in PSCI code, but TEE mediator will need a call that is
>>>> fully compatible with ARM SMCCC v1.0.
>>>>
>>>> This patch adds a wrapper for both arm32 and arm64. In the case of
>>>> arm32, the wrapper is just an alias to the ARM SMCCC v1.1 as the
>>>> convention is the same.
>>>>
>>>> CC: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
>>>> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
>>>> [julien: Rework the wrapper to make it closer to SMCC 1.1 wrapper]
>>>> Signed-off-by: Julien Grall <julien.grall@arm.com>
>>>
>>> I have been struggling to find the old doc for SMCCC v1.0, all the
>>> references have been updated to v1.1 online now. Do you have a link?
>>
>> Are you sure? All the references are still to v1.0 (DEN 0028B). See [1].
>
> The lack of version in the doc confused me.
>
>
>>>> diff --git a/xen/arch/arm/arm64/smc.S b/xen/arch/arm/arm64/smc.S
>>>> new file mode 100644
>>>> index 0000000000..b0752be57e
>>>> --- /dev/null
>>>> +++ b/xen/arch/arm/arm64/smc.S
>>>> @@ -0,0 +1,32 @@
>>>> +/*
>>>> + * xen/arch/arm/arm64/smc.S
>>>> + *
>>>> + * Wrapper for Secure Monitors Calls
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License as published by
>>>> + * the Free Software Foundation; either version 2 of the License.
>>>> + *
>>>> + * 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.
>>>> + */
>>>> +
>>>> +#include <asm/asm_defns.h>
>>>> +#include <asm/macros.h>
>>>> +
>>>> +/*
>>>> + * void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
>>>> + * register_t a3, register_t a4, register_t a5,
>>>> + * register_t a6, register_t a7,
>>>> + * struct arm_smccc_res *res)
>>>> + */
>>>> +ENTRY(__arm_smccc_1_0_smc)
>>>> + smc #0
>>>> + ldr x4, [sp]
>>>> + cbz x4, 1f /* No need to store the result */
>>>> + stp x0, x1, [x4, #SMCCC_RES_a0]
>>>> + stp x2, x3, [x4, #SMCCC_RES_a2]
>>>> +1:
>>>> + ret
>>>
>>> As I mentioned, I couldn't find the doc, but it looks like the Linux
>>> implementation always copies back the results
>>> (arch/arm64/kernel/smccc-call.S)? Shouldn't we zero x0-x3 at least?
>> Could you provide more details on what looks wrong?
>>
>> The results are copied in the array res using stp instructions. The only
>> difference with Linux implementation is we don't handle quirk.
>
> The only difference is that in this implementation we handle `res' being
> NULL, which I think is a good idea:
Oh yeah I forgot that difference :/. I added it to keep the behavior
similar to the SMCCC v1.1 implementation.
>
> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>
Thank you!
Cheers,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps
2018-09-27 22:34 ` Stefano Stabellini
@ 2018-09-28 9:27 ` Julien Grall
0 siblings, 0 replies; 23+ messages in thread
From: Julien Grall @ 2018-09-28 9:27 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: volodymyr_babchuk, xen-devel
Hi,
On 09/27/2018 11:34 PM, Stefano Stabellini wrote:
> On Wed, 26 Sep 2018, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 09/26/2018 05:53 PM, Stefano Stabellini wrote:
>>> On Tue, 25 Sep 2018, Julien Grall wrote:
>>>> Some capababilities are set right during boot and will never change
>>>> afterwards. At the moment, the function cpu_have_caps will check whether
>>>> the cap is enabled from the memory.
>>>>
>>>> It is possible to avoid the load from the memory by using an
>>>> ALTERNATIVE. With that the check is just reduced to 1 instruction.
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@arm.com>
>>>
>>> I enjoyed reading the patch :-) But I don't think it is worth going
>>> into this extreme level of optimization. test_bit is efficient enough,
>>> right? What do you think we need to use alternatives just to check one
>>> bit?
>>
>> We already have an helper using test_bit (see cpus_have_cap). However test_bit
>> requires to load the word from the memory. This is an overhead when the
>> decision never change after boot.
>>
>> One load may be insignificant by itself (thought may have a cache miss), but
>> if you are in hotpath this is a win in long term.
>>
>> The mechanism is very similar to static key but for the poor (I don't have
>> much time to implement better for now). We already use similar construction on
>> other places (see CHECK_WORKAROUND_HELPER).
>
> I like the mechanism and the little ALTERNATIVE trick. I can see it
> could very useful in some cases. It is just that it is a bit of a waste
> to use it on SMCCC virtualization -- SMCCC calls cannot be done often
> enough for this to make a difference.
I would not be so sure ;). SMC can be called at *every* entry and exit
into the hypervisor to apply SSBD workaround.
While SSBD will directly call arm_smccc_1_1_smc (and not the generic
one), I would not rule out more hotpath with SMC call in it.
Cheers,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc
2018-09-27 22:41 ` Stefano Stabellini
@ 2018-10-01 10:01 ` Julien Grall
0 siblings, 0 replies; 23+ messages in thread
From: Julien Grall @ 2018-10-01 10:01 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: volodymyr_babchuk, xen-devel
Hi Stefano,
On 09/27/2018 11:41 PM, Stefano Stabellini wrote:
> On Wed, 26 Sep 2018, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 09/26/2018 12:57 AM, Stefano Stabellini wrote:
>>> On Tue, 25 Sep 2018, Julien Grall wrote:
>>>> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
>>>> index 941eec921b..02737e6caa 100644
>>>> --- a/xen/arch/arm/psci.c
>>>> +++ b/xen/arch/arm/psci.c
>>>> @@ -42,42 +42,53 @@ uint32_t smccc_ver;
>>>> static uint32_t psci_cpu_on_nr;
>>>> +#define PSCI_RET(res) ((int32_t)(res).a0)
>>>> +
>>>> int call_psci_cpu_on(int cpu)
>>>> {
>>>> - return call_smc(psci_cpu_on_nr, cpu_logical_map(cpu),
>>>> __pa(init_secondary), 0);
>>>> + struct arm_smccc_res res;
>>>> +
>>>> + arm_smccc_smc(psci_cpu_on_nr, cpu_logical_map(cpu),
>>>> __pa(init_secondary),
>>>> + &res);
>>>> +
>>>> + return (int32_t)res.a0;
>>>> }
>>>
>>> Can't we use PSCI_RET(res) here?
>>
>> I missed that one. I will update it.
>>
>>>
>>> Also in general, should we care about the type mismatch int32_t vs. int
>>> which is the return type of this function?
>>
>> The only issue I could see is if sizeof(int) < sizeof(int32_t). If that
>> happen, then psci.c would be our least concern as we always assume int would
>> at least 32-bit wide.
>>
>> I would prefer to keep the return of the function int and casting the result
>> with (int32_t). The latter is helpful to know what is the size of the result
>> (a0 is 64-bit).
>
> It is a good idea to keep the cast. I don't have a strong opinion on
> whether the functions should return int or int32_t. The only question is
> whether we want to cast to (int32_t) or to (int). I would prefer to cast
> to the same type of the return of the function. So if we keep int as
> return type, then casting to (int). However, given that in practice it
> makes no difference, I can ack the patch in any case.
I would prefer to stick with the current approach.
Cheers,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2018-10-01 10:01 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-25 17:20 [PATCH v2 0/6] xen/arm: SMCCC fixup and improvement Julien Grall
2018-09-25 17:20 ` [PATCH v2 1/6] xen/arm: smccc-1.1: Make return values unsigned long Julien Grall
2018-09-25 23:18 ` Stefano Stabellini
2018-09-25 17:20 ` [PATCH v2 2/6] xen/arm: smccc-1.1: Handle function result as parameters Julien Grall
2018-09-25 23:18 ` Stefano Stabellini
2018-09-25 17:20 ` [PATCH v2 3/6] xen/arm: add SMC wrapper that is compatible with SMCCC v1.0 Julien Grall
2018-09-25 23:50 ` Stefano Stabellini
2018-09-26 18:45 ` Julien Grall
2018-09-27 23:02 ` Stefano Stabellini
2018-09-28 9:20 ` Julien Grall
2018-09-25 17:20 ` [PATCH v2 4/6] xen/arm: cpufeature: Add helper to check constant caps Julien Grall
2018-09-26 16:53 ` Stefano Stabellini
2018-09-26 19:00 ` Julien Grall
2018-09-27 22:34 ` Stefano Stabellini
2018-09-28 9:27 ` Julien Grall
2018-09-25 17:20 ` [PATCH v2 5/6] xen/arm: smccc: Add wrapper to automatically select the calling convention Julien Grall
2018-09-25 23:52 ` Stefano Stabellini
2018-09-26 11:24 ` Volodymyr Babchuk
2018-09-25 17:20 ` [PATCH v2 6/6] xen/arm: Replace call_smc with arm_smccc_smc Julien Grall
2018-09-25 23:57 ` Stefano Stabellini
2018-09-26 19:04 ` Julien Grall
2018-09-27 22:41 ` Stefano Stabellini
2018-10-01 10:01 ` Julien Grall
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.