xen/arm: Add ARCH_WORKAROUND_2 probing
authorJulien Grall <julien.grall@arm.com>
Tue, 12 Jun 2018 11:36:34 +0000 (12:36 +0100)
committerJulien Grall <julien.grall@arm.com>
Fri, 22 Jun 2018 01:59:08 +0000 (02:59 +0100)
As for Spectre variant-2, we rely on SMCCC 1.1 to provide the discovery
mechanism for detecting the SSBD mitigation.

A new capability is also allocated for that purpose, and a config
option.

This is part of XSA-263.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/Kconfig
xen/arch/arm/cpuerrata.c
xen/include/asm-arm/cpuerrata.h
xen/include/asm-arm/cpufeature.h
xen/include/asm-arm/smccc.h

index 4dc7ef53519eff1a977177f3f35b0a85e77396aa..2cbe9dd43bd636c87b44fffe4514b6a0c1b1204e 100644 (file)
@@ -71,6 +71,16 @@ config SBSA_VUART_CONSOLE
          Allows a guest to use SBSA Generic UART as a console. The
          SBSA Generic UART implements a subset of ARM PL011 UART.
 
+config ARM_SSBD
+       bool "Speculative Store Bypass Disable" if EXPERT = "y"
+       depends on HAS_ALTERNATIVE
+       default y
+       help
+         This enables mitigation of bypassing of previous stores by speculative
+         loads.
+
+         If unsure, say Y.
+
 endmenu
 
 menu "ARM errata workaround via the alternative framework"
index b829d226ef5c819789c0cea9066e842abfe5ebc8..03f78fec96656dd574a7c05a608b999224ab9d30 100644 (file)
@@ -237,6 +237,58 @@ static int enable_ic_inv_hardening(void *data)
 
 #endif
 
+#ifdef CONFIG_ARM_SSBD
+
+/*
+ * Assembly code may use the variable directly, so we need to make sure
+ * it fits in a register.
+ */
+DEFINE_PER_CPU_READ_MOSTLY(register_t, ssbd_callback_required);
+
+static bool has_ssbd_mitigation(const struct arm_cpu_capabilities *entry)
+{
+    struct arm_smccc_res res;
+    bool required;
+
+    if ( smccc_ver < SMCCC_VERSION(1, 1) )
+        return false;
+
+    /*
+     * The probe function return value is either negative (unsupported
+     * or mitigated), positive (unaffected), or zero (requires
+     * mitigation). We only need to do anything in the last case.
+     */
+    arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FID,
+                      ARM_SMCCC_ARCH_WORKAROUND_2_FID, &res);
+
+    switch ( (int)res.a0 )
+    {
+    case ARM_SMCCC_NOT_SUPPORTED:
+        return false;
+
+    case ARM_SMCCC_NOT_REQUIRED:
+        return false;
+
+    case ARM_SMCCC_SUCCESS:
+        required = true;
+        break;
+
+    case 1: /* Mitigation not required on this CPU. */
+        required = false;
+        break;
+
+    default:
+        ASSERT_UNREACHABLE();
+        return false;
+    }
+
+    if ( required )
+        this_cpu(ssbd_callback_required) = 1;
+
+    return required;
+}
+#endif
+
 #define MIDR_RANGE(model, min, max)     \
     .matches = is_affected_midr_range,  \
     .midr_model = model,                \
@@ -337,6 +389,12 @@ static const struct arm_cpu_capabilities arm_errata[] = {
         MIDR_ALL_VERSIONS(MIDR_CORTEX_A15),
         .enable = enable_ic_inv_hardening,
     },
+#endif
+#ifdef CONFIG_ARM_SSBD
+    {
+        .capability = ARM_SSBD,
+        .matches = has_ssbd_mitigation,
+    },
 #endif
     {},
 };
index 4e45b237c871339f4578d707cbf48898dacb4e29..e628d3ff568d6a811b3a085f965f47de02d73ef1 100644 (file)
@@ -27,9 +27,30 @@ static inline bool check_workaround_##erratum(void)             \
 
 CHECK_WORKAROUND_HELPER(766422, ARM32_WORKAROUND_766422, CONFIG_ARM_32)
 CHECK_WORKAROUND_HELPER(834220, ARM64_WORKAROUND_834220, CONFIG_ARM_64)
+CHECK_WORKAROUND_HELPER(ssbd, ARM_SSBD, CONFIG_ARM_SSBD)
 
 #undef CHECK_WORKAROUND_HELPER
 
+#ifdef CONFIG_ARM_SSBD
+
+#include <asm/current.h>
+
+DECLARE_PER_CPU(register_t, ssbd_callback_required);
+
+static inline bool cpu_require_ssbd_mitigation(void)
+{
+    return this_cpu(ssbd_callback_required);
+}
+
+#else
+
+static inline bool cpu_require_ssbd_mitigation(void)
+{
+    return false;
+}
+
+#endif
+
 #endif /* __ARM_CPUERRATA_H__ */
 /*
  * Local variables:
index c5d046218b6160597e07b75bdfd51891033767f3..3de6b543015633b1bd3a6c7f1f181663b27d12b4 100644 (file)
@@ -43,8 +43,9 @@
 #define SKIP_SYNCHRONIZE_SERROR_ENTRY_EXIT 5
 #define SKIP_CTXT_SWITCH_SERROR_SYNC 6
 #define ARM_HARDEN_BRANCH_PREDICTOR 7
+#define ARM_SSBD 8
 
-#define ARM_NCAPS           8
+#define ARM_NCAPS           9
 
 #ifndef __ASSEMBLY__
 
index 8342cc33fee3ecd9475c42e0d30e7f13c7f0e367..a6804cec993c22e09ee57ccc2e56382955412b33 100644 (file)
@@ -258,7 +258,14 @@ struct arm_smccc_res {
                       ARM_SMCCC_OWNER_ARCH,         \
                       0x8000)
 
+#define ARM_SMCCC_ARCH_WORKAROUND_2_FID             \
+    ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,         \
+                       ARM_SMCCC_CONV_32,           \
+                       ARM_SMCCC_OWNER_ARCH,        \
+                       0x7FFF)
+
 /* SMCCC error codes */
+#define ARM_SMCCC_NOT_REQUIRED          (-2)
 #define ARM_SMCCC_ERR_UNKNOWN_FUNCTION  (-1)
 #define ARM_SMCCC_NOT_SUPPORTED         (-1)
 #define ARM_SMCCC_SUCCESS               (0)