]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
xen/arm: Add sb instruction support
authorBertrand Marquis <bertrand.marquis@arm.com>
Mon, 13 Jun 2022 12:53:12 +0000 (13:53 +0100)
committerStefano Stabellini <stefano.stabellini@xilinx.com>
Thu, 16 Jun 2022 00:33:40 +0000 (17:33 -0700)
This patch is adding sb instruction support when it is supported by a
CPU on arm64.
A new cpu feature capability system is introduced to enable alternative
code using sb instruction when it is supported by the processor. This is
decided based on the isa64 system register value and use a new hardware
capability ARM_HAS_SB.

The sb instruction is encoded using its hexadecimal value to avoid
recursive macro and support old compilers not having support for sb
instruction.

Arm32 instruction support is added but it is not enabled at the moment
due to the lack of hardware supporting it.

Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
xen/arch/arm/cpufeature.c
xen/arch/arm/include/asm/cpufeature.h
xen/arch/arm/include/asm/macros.h
xen/arch/arm/setup.c
xen/arch/arm/smpboot.c

index a58965f7b9bfe21aceda47b36db38ed8d44ab7a2..62d5e1770adb169bada39021dca2706ed4bbfe9c 100644 (file)
@@ -26,6 +26,24 @@ DECLARE_BITMAP(cpu_hwcaps, ARM_NCAPS);
 
 struct cpuinfo_arm __read_mostly guest_cpuinfo;
 
+#ifdef CONFIG_ARM_64
+static bool has_sb_instruction(const struct arm_cpu_capabilities *entry)
+{
+    return system_cpuinfo.isa64.sb;
+}
+#endif
+
+static const struct arm_cpu_capabilities arm_features[] = {
+#ifdef CONFIG_ARM_64
+    {
+        .desc = "Speculation barrier instruction (SB)",
+        .capability = ARM_HAS_SB,
+        .matches = has_sb_instruction,
+    },
+#endif
+    {},
+};
+
 void update_cpu_capabilities(const struct arm_cpu_capabilities *caps,
                              const char *info)
 {
@@ -70,6 +88,16 @@ void __init enable_cpu_capabilities(const struct arm_cpu_capabilities *caps)
     }
 }
 
+void check_local_cpu_features(void)
+{
+    update_cpu_capabilities(arm_features, "enabled support for");
+}
+
+void __init enable_cpu_features(void)
+{
+    enable_cpu_capabilities(arm_features);
+}
+
 /*
  * Run through the enabled capabilities and enable() them on the calling CPU.
  * If enabling of any capability fails the error is returned. After enabling a
index f7368766c07c0e776d5a9868edb0d615a81d2a87..24c01d2b9dbc0d5ace934336defd1617444d2270 100644 (file)
@@ -67,8 +67,9 @@
 #define ARM_WORKAROUND_BHB_LOOP_24 13
 #define ARM_WORKAROUND_BHB_LOOP_32 14
 #define ARM_WORKAROUND_BHB_SMCC_3 15
+#define ARM_HAS_SB 16
 
-#define ARM_NCAPS           16
+#define ARM_NCAPS           17
 
 #ifndef __ASSEMBLY__
 
@@ -78,6 +79,9 @@
 
 extern DECLARE_BITMAP(cpu_hwcaps, ARM_NCAPS);
 
+void check_local_cpu_features(void);
+void enable_cpu_features(void);
+
 static inline bool cpus_have_cap(unsigned int num)
 {
     if ( num >= ARM_NCAPS )
index 1aa373760f98d21f8af05baaa6495dafb843a1b0..dc791245df764a39babed3f2e015473aa1d723e9 100644 (file)
@@ -5,13 +5,30 @@
 # error "This file should only be included in assembly file"
 #endif
 
+#include <asm/alternative.h>
+
     /*
      * Speculative barrier
-     * XXX: Add support for the 'sb' instruction
      */
     .macro sb
+alternative_if_not ARM_HAS_SB
     dsb nsh
     isb
+alternative_else
+    /*
+     * SB encoding in hexadecimal to prevent recursive macro.
+     * extra nop is required to keep same number of instructions on both sides
+     * of the alternative.
+     */
+#if defined(CONFIG_ARM_32)
+    .inst 0xf57ff070
+#elif defined(CONFIG_ARM_64)
+    .inst 0xd50330ff
+#else
+#   error "missing sb encoding for ARM variant"
+#endif
+    nop
+alternative_endif
     .endm
 
 #if defined (CONFIG_ARM_32)
index 6016471d37750fc12e4fbc569c0017cf57eb6b0d..577c54e6fbfa469f12b9a4d0bfcf7b2e33c09dbe 100644 (file)
@@ -964,6 +964,8 @@ void __init start_xen(unsigned long boot_phys_offset,
      */
     check_local_cpu_errata();
 
+    check_local_cpu_features();
+
     init_xen_time();
 
     gic_init();
@@ -1033,6 +1035,7 @@ void __init start_xen(unsigned long boot_phys_offset,
      */
     apply_alternatives_all();
     enable_errata_workarounds();
+    enable_cpu_features();
 
     /* Create initial domain 0. */
     if ( !is_dom0less_mode() )
index 22fede6600ec5b88afa544b940f6fb661342ee49..3f62f3a44feea145cbd8e62f8143d8d9cc1f06ea 100644 (file)
@@ -395,6 +395,7 @@ void start_secondary(void)
     local_abort_enable();
 
     check_local_cpu_errata();
+    check_local_cpu_features();
 
     printk(XENLOG_DEBUG "CPU %u booted.\n", smp_processor_id());