[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/6] xen/arm: Introduce arm_smccc_guest_smc()



Both {get,set}_user_reg() are out-of-line functions, leading to awful code
generation.

Introduce arm_smccc_guest_smc() to operate directly on guest registers.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Julien Grall <julien@xxxxxxx>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
CC: Bertrand Marquis <bertrand.marquis@xxxxxxx>
CC: Michal Orzel <michal.orzel@xxxxxxx>
CC: Jan Setje-Eilers <Jan.SetjeEilers@xxxxxxxxxx>

For arm64:

  add/remove: 0/0 grow/shrink: 2/4 up/down: 27/-864 (-837)
  Function                                     old     new   delta
  symbols_addresses                          35096   35120     +24
  symbols_names                              42958   42961      +3
  imx8qm_smc                                   544     348    -196
  scmi_handle_smc                              372     152    -220
  imx8m_smc                                    576     356    -220
  zynqmp_eemi                                  864     636    -228

For arm32:

  add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-160 (-160)
  Function                                     old     new   delta
  scmi_handle_smc                              392     232    -160
---
 xen/arch/arm/firmware/scmi-smc.c            | 16 +-----------
 xen/arch/arm/include/asm/smccc.h            | 29 +++++++++++++++++++++
 xen/arch/arm/platforms/imx8m.c              | 16 +-----------
 xen/arch/arm/platforms/imx8qm.c             | 16 +-----------
 xen/arch/arm/platforms/xilinx-zynqmp-eemi.c | 17 ++----------
 5 files changed, 34 insertions(+), 60 deletions(-)

diff --git a/xen/arch/arm/firmware/scmi-smc.c b/xen/arch/arm/firmware/scmi-smc.c
index 0835ddeeeccc..a0cc6c6192f8 100644
--- a/xen/arch/arm/firmware/scmi-smc.c
+++ b/xen/arch/arm/firmware/scmi-smc.c
@@ -50,7 +50,6 @@ static bool scmi_is_valid_smc_id(uint32_t fid)
 static bool scmi_handle_smc(struct cpu_user_regs *regs)
 {
     uint32_t fid = (uint32_t)get_user_reg(regs, 0);
-    struct arm_smccc_res res;
 
     if ( !scmi_is_valid_smc_id(fid) )
         return false;
@@ -63,20 +62,7 @@ static bool scmi_handle_smc(struct cpu_user_regs *regs)
     }
 
     /* For the moment, forward the SCMI Request to FW running at EL3 */
-    arm_smccc_1_1_smc(fid,
-                      get_user_reg(regs, 1),
-                      get_user_reg(regs, 2),
-                      get_user_reg(regs, 3),
-                      get_user_reg(regs, 4),
-                      get_user_reg(regs, 5),
-                      get_user_reg(regs, 6),
-                      get_user_reg(regs, 7),
-                      &res);
-
-    set_user_reg(regs, 0, res.a0);
-    set_user_reg(regs, 1, res.a1);
-    set_user_reg(regs, 2, res.a2);
-    set_user_reg(regs, 3, res.a3);
+    arm_smccc_guest_smc(regs);
 
     return true;
 }
diff --git a/xen/arch/arm/include/asm/smccc.h b/xen/arch/arm/include/asm/smccc.h
index 53cdddb690b7..832157f43734 100644
--- a/xen/arch/arm/include/asm/smccc.h
+++ b/xen/arch/arm/include/asm/smccc.h
@@ -202,6 +202,21 @@ 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__)
+
+/* Make an SMCCC v1.1 compliant SMC call with guest register state. */
+static inline void arm_smccc_guest_smc(struct cpu_user_regs *regs)
+{
+    struct arm_smccc_res res;
+
+    arm_smccc_1_1_smc(regs->r0, regs->r1, regs->r2, regs->r3,
+                      regs->r4, regs->r5, regs->r6, regs->r7, &res);
+
+    regs->r0 = res.a0;
+    regs->r1 = res.a1;
+    regs->r2 = res.a2;
+    regs->r3 = res.a3;
+}
+
 #else
 
 void __arm_smccc_1_0_smc(register_t a0, register_t a1, register_t a2,
@@ -251,6 +266,20 @@ void __arm_smccc_1_0_smc(register_t a0, register_t a1, 
register_t a2,
             arm_smccc_1_0_smc(__VA_ARGS__);                     \
     } while ( 0 )
 
+/* Make an SMCCC v1.1 compliant SMC call with guest register state. */
+static inline void arm_smccc_guest_smc(struct cpu_user_regs *regs)
+{
+    struct arm_smccc_res res;
+
+    arm_smccc_1_1_smc(regs->x0, regs->x1, regs->x2, regs->x3,
+                      regs->x4, regs->x5, regs->x6, regs->x7, &res);
+
+    regs->x0 = res.a0;
+    regs->x1 = res.a1;
+    regs->x2 = res.a2;
+    regs->x3 = res.a3;
+}
+
 /*
  * struct arm_smccc_1_2_regs - Arguments for or Results from SMC call
  * @a0-a17 argument values from registers 0 to 17
diff --git a/xen/arch/arm/platforms/imx8m.c b/xen/arch/arm/platforms/imx8m.c
index 669dd517e057..efb0ad20d6e8 100644
--- a/xen/arch/arm/platforms/imx8m.c
+++ b/xen/arch/arm/platforms/imx8m.c
@@ -50,7 +50,6 @@ static bool imx8m_smc(struct cpu_user_regs *regs)
 {
     uint32_t function_id = get_user_reg(regs, 0);
     uint32_t subfunction_id = get_user_reg(regs, 1);
-    struct arm_smccc_res res;
 
     if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
     {
@@ -122,20 +121,7 @@ static bool imx8m_smc(struct cpu_user_regs *regs)
         return false;
     }
 
-    arm_smccc_1_1_smc(function_id,
-                      subfunction_id,
-                      get_user_reg(regs, 2),
-                      get_user_reg(regs, 3),
-                      get_user_reg(regs, 4),
-                      get_user_reg(regs, 5),
-                      get_user_reg(regs, 6),
-                      get_user_reg(regs, 7),
-                      &res);
-
-    set_user_reg(regs, 0, res.a0);
-    set_user_reg(regs, 1, res.a1);
-    set_user_reg(regs, 2, res.a2);
-    set_user_reg(regs, 3, res.a3);
+    arm_smccc_guest_smc(regs);
 
     return true;
 }
diff --git a/xen/arch/arm/platforms/imx8qm.c b/xen/arch/arm/platforms/imx8qm.c
index 3600a073e8ba..7249e14ab640 100644
--- a/xen/arch/arm/platforms/imx8qm.c
+++ b/xen/arch/arm/platforms/imx8qm.c
@@ -67,7 +67,6 @@ static bool imx8qm_smc(struct cpu_user_regs *regs)
 {
     uint32_t function_id = get_user_reg(regs, 0);
     uint32_t subfunction_id = get_user_reg(regs, 1);
-    struct arm_smccc_res res;
 
     if ( !cpus_have_const_cap(ARM_SMCCC_1_1) )
     {
@@ -106,20 +105,7 @@ static bool imx8qm_smc(struct cpu_user_regs *regs)
     }
 
  allow_call:
-    arm_smccc_1_1_smc(function_id,
-                      subfunction_id,
-                      get_user_reg(regs, 2),
-                      get_user_reg(regs, 3),
-                      get_user_reg(regs, 4),
-                      get_user_reg(regs, 5),
-                      get_user_reg(regs, 6),
-                      get_user_reg(regs, 7),
-                      &res);
-
-    set_user_reg(regs, 0, res.a0);
-    set_user_reg(regs, 1, res.a1);
-    set_user_reg(regs, 2, res.a2);
-    set_user_reg(regs, 3, res.a3);
+    arm_smccc_guest_smc(regs);
 
     return true;
 }
diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c 
b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
index 2053ed7ac5f6..326c8a1ba6e5 100644
--- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
+++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
@@ -51,7 +51,6 @@ static inline bool domain_has_reset_access(struct domain *d, 
uint32_t rst)
 
 bool zynqmp_eemi(struct cpu_user_regs *regs)
 {
-    struct arm_smccc_res res;
     uint32_t fid = get_user_reg(regs, 0);
     uint32_t nodeid = get_user_reg(regs, 1);
     unsigned int pm_fn = fid & 0xFFFF;
@@ -187,20 +186,8 @@ bool zynqmp_eemi(struct cpu_user_regs *regs)
      * can forward the whole command to firmware without additional
      * parameters checks.
      */
-    arm_smccc_1_1_smc(get_user_reg(regs, 0),
-                      get_user_reg(regs, 1),
-                      get_user_reg(regs, 2),
-                      get_user_reg(regs, 3),
-                      get_user_reg(regs, 4),
-                      get_user_reg(regs, 5),
-                      get_user_reg(regs, 6),
-                      get_user_reg(regs, 7),
-                      &res);
-
-    set_user_reg(regs, 0, res.a0);
-    set_user_reg(regs, 1, res.a1);
-    set_user_reg(regs, 2, res.a2);
-    set_user_reg(regs, 3, res.a3);
+    arm_smccc_guest_smc(regs);
+
     return true;
 
 done:
-- 
2.39.5




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.