All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@arm.com>
To: xen-devel@lists.xen.org
Cc: Julien Grall <julien.grall@arm.com>,
	sstabellini@kernel.org, volodymyr_babchuk@epam.com,
	andre.przywara@linaro.org
Subject: [PATCH v2 10/15] xen/arm: smccc: Implement SMCCC v1.1 inline primitive
Date: Thu,  8 Feb 2018 19:21:58 +0000	[thread overview]
Message-ID: <20180208192203.9556-11-julien.grall@arm.com> (raw)
In-Reply-To: <20180208192203.9556-1-julien.grall@arm.com>

One of the major improvement of SMCCC v1.1 is that it only clobbers the
first 4 registers, both on 32 and 64bit. This means that it becomes very
easy to provide an inline version of the SMC call primitive, and avoid
performing a function call to stash the registers that woudl otherwise
be clobbered by SMCCC v1.0.

This patch has been adapted to Xen from Linux commit f2d3b2e8759a. The
changes mades are:
    - Using Xen coding style
    - Remove HVC as not used by Xen
    - Add arm_smccc_res structure

 Reviewed-by: Robin Murphy <robin.murphy@arm.com>
 Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
 Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

Signed-off-by: Julien Grall <julien.grall@arm.com>

---

    Note that the patch is in arm64/for-next/core and should be merged
    in master soon.

    Changes in v2:
        - Patch added
---
 xen/include/asm-arm/smccc.h | 119 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/xen/include/asm-arm/smccc.h b/xen/include/asm-arm/smccc.h
index bc067892c7..154772b728 100644
--- a/xen/include/asm-arm/smccc.h
+++ b/xen/include/asm-arm/smccc.h
@@ -78,6 +78,125 @@ static inline uint32_t smccc_get_owner(register_t funcid)
     return (funcid >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK;
 }
 
+/*
+ * struct arm_smccc_res - Result from SMC call
+ * @a0 - @a3 result values from registers 0 to 3
+ */
+struct arm_smccc_res {
+    unsigned long a0;
+    unsigned long a1;
+    unsigned long a2;
+    unsigned long a3;
+};
+
+/* SMCCC v1.1 implementation madness follows */
+#define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
+
+#define __count_args(...)                               \
+    ___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
+
+#define __constraint_write_0                        \
+    "+r" (r0), "=&r" (r1), "=&r" (r2), "=&r" (r3)
+#define __constraint_write_1                        \
+    "+r" (r0), "+r" (r1), "=&r" (r2), "=&r" (r3)
+#define __constraint_write_2                        \
+    "+r" (r0), "+r" (r1), "+r" (r2), "=&r" (r3)
+#define __constraint_write_3                        \
+    "+r" (r0), "+r" (r1), "+r" (r2), "+r" (r3)
+#define __constraint_write_4    __constraint_write_3
+#define __constraint_write_5    __constraint_write_4
+#define __constraint_write_6    __constraint_write_5
+#define __constraint_write_7    __constraint_write_6
+
+#define __constraint_read_0
+#define __constraint_read_1
+#define __constraint_read_2
+#define __constraint_read_3
+#define __constraint_read_4 "r" (r4)
+#define __constraint_read_5 __constraint_read_4, "r" (r5)
+#define __constraint_read_6 __constraint_read_5, "r" (r6)
+#define __constraint_read_7 __constraint_read_6, "r" (r7)
+
+#define __declare_arg_0(a0, res)                        \
+    struct arm_smccc_res    *___res = res;              \
+    register uin32_t        r0 asm("r0") = 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  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  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
+
+#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
+
+#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res)    \
+    __declare_arg_4(a0, a1, a2, a3, a4, res);           \
+    register typeof(a5) r5 asm("r5") = a5
+
+#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res)    \
+    __declare_arg_5(a0, a1, a2, a3, a4, a5, res);           \
+    register typeof(a6) r6 asm("r6") = a6
+
+#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res)    \
+    __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res);           \
+    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__)
+
+#define ___constraints(count)                       \
+    : __constraint_write_ ## count                  \
+    : __constraint_read_ ## count                   \
+    : "memory"
+#define __constraints(count)    ___constraints(count)
+
+/*
+ * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
+ *
+ * This is a variadic macro taking one to eight source arguments, and
+ * an optional return structure.
+ *
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This macro is used to make SMC calls following SMC Calling Convention v1.1.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the SMC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the SMC instruction if not NULL.
+ *
+ * We have an output list that is not necessarily used, and GCC feels
+ * entitled to optimise the whole sequence away. "volatile" is what
+ * makes it stick.
+ */
+#define arm_smccc_1_1_smc(...)                                  \
+    do {                                                        \
+        __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
+        asm volatile("smc #0\n"                                 \
+                     __constraints(__count_args(__VA_ARGS__))); \
+        if ( ___res )                                           \
+        *___res = (typeof(*___res)){r0, r1, r2, r3};            \
+    } while ( 0 )
+
 #endif
 
 /*
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2018-02-08 19:21 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-08 19:21 [PATCH v2 00/15] xen/arm: PSCI 1.1 and SMCCC-1.1 support and XSA-254 variant 2 update Julien Grall
2018-02-08 19:21 ` [PATCH v2 01/15] xen/arm: psci: Rework the PSCI definitions Julien Grall
2018-02-08 19:21 ` [PATCH v2 02/15] xen/arm: vpsci: Add support for PSCI 1.1 Julien Grall
2018-02-09 16:07   ` Volodymyr Babchuk
2018-02-09 16:13     ` Julien Grall
2018-02-09 16:30       ` Volodymyr Babchuk
2018-02-12 14:43   ` Wei Liu
2018-02-12 20:12   ` Mirela Simonovic
2018-02-12 21:41     ` Julien Grall
2018-02-12 23:16       ` Mirela Simonovic
2018-02-12 23:44         ` Julien Grall
2018-02-14 19:14           ` Mirela Simonovic
2018-02-15 11:25             ` Julien Grall
2018-02-08 19:21 ` [PATCH v2 03/15] xen/arm: vsmc: Implement SMCCC 1.1 Julien Grall
2018-02-09 16:08   ` Volodymyr Babchuk
2018-02-09 16:15     ` Julien Grall
2018-02-09 16:47       ` Volodymyr Babchuk
2018-02-08 19:21 ` [PATCH v2 04/15] xen/arm: vsmc: Implement SMCCC_ARCH_WORKAROUND_1 BP hardening support Julien Grall
2018-02-20  0:26   ` Stefano Stabellini
2018-02-08 19:21 ` [PATCH v2 05/15] xen/arm: Adapt smccc.h to be able to use it in assembly code Julien Grall
2018-02-20  0:28   ` Stefano Stabellini
2018-02-08 19:21 ` [PATCH v2 06/15] xen/arm64: Implement a fast path for handling SMCCC_ARCH_WORKAROUND_1 Julien Grall
2018-02-08 19:21 ` [PATCH v2 07/15] xen/arm64: Print a per-CPU message with the BP hardening method used Julien Grall
2018-02-09 16:43   ` Volodymyr Babchuk
2018-02-08 19:21 ` [PATCH v2 08/15] xen/arm: smccc: Add macros SMCCC_VERSION, SMCCC_VERSION_{MINOR, MAJOR} Julien Grall
2018-02-09 16:11   ` Volodymyr Babchuk
2018-02-08 19:21 ` [PATCH v2 09/15] xen/arm: psci: Detect SMCCC version Julien Grall
2018-02-09 17:04   ` Volodymyr Babchuk
2018-02-09 17:09     ` Julien Grall
2018-02-12 14:43       ` Volodymyr Babchuk
2018-02-12 15:06         ` Julien Grall
2018-02-08 19:21 ` Julien Grall [this message]
2018-02-08 19:21 ` [PATCH v2 11/15] xen/arm64: Add ARM_SMCCC_ARCH_WORKAROUND_1 BP hardening support Julien Grall
2018-02-12 16:55   ` Volodymyr Babchuk
2018-02-12 17:12     ` Julien Grall
2018-02-12 17:20       ` Volodymyr Babchuk
2018-02-12 17:26         ` Julien Grall
2018-02-08 19:22 ` [PATCH v2 12/15] xen/arm64: Kill PSCI_GET_VERSION as a variant-2 workaround Julien Grall
2018-02-13 11:59   ` Volodymyr Babchuk
2018-02-08 19:22 ` [PATCH v2 13/15] xen/arm: vpsci: Remove parameter 'ver' from do_common_cpu Julien Grall
2018-02-08 19:22 ` [PATCH v2 14/15] xen/arm: psci: Consolidate PSCI version print Julien Grall
2018-02-09 16:40   ` Volodymyr Babchuk
2018-02-08 19:22 ` [PATCH v2 15/15] xen/arm: psci: Prefix with static any functions not exported Julien Grall
2018-02-09 16:40   ` Volodymyr Babchuk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180208192203.9556-11-julien.grall@arm.com \
    --to=julien.grall@arm.com \
    --cc=andre.przywara@linaro.org \
    --cc=sstabellini@kernel.org \
    --cc=volodymyr_babchuk@epam.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.