> Date: Tue, 1 May 2018 11:55:00 +0200 (CEST)
> From: Mark Kettenis <mark.kette...@xs4all.nl>
> 
> So after adding a quick hack to mitigate Spectre variant 2 to ARM
> Trusted Firmware (ATF), ARM actually designed a proper solution that
> minimizes the performance loss and makes the presence of the
> workaround detectable.  This is all documented in an update of the SMC
> Calling Convention (SMCCC) standard.
> 
> The diff below implements support for this solution while keeping
> support for the hack.  While ARM strongly suggests vendors to update
> to a version of ATF that implements SMCCC 1.1 the current ATF for the
> Marvell ARMADA 8040 hasn't been updated yet (but does include the
> initial hack).

So it turns out that while I wasn't paying attention, the Marvell
folks backported SMCCC 1.1 support to their ATF fork.  This means we
can drop support for the PSCI_VERSION hack without leaving
MACCHIATOBin owener out in the cold.  I think the code simplification
is worth it.  It also means we can tell whether a machine is safe or
not from a dmesg.

ok?

Index: dev/fdt/psci.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/psci.c,v
retrieving revision 1.7
diff -u -p -r1.7 psci.c
--- dev/fdt/psci.c      3 May 2018 09:45:57 -0000       1.7
+++ dev/fdt/psci.c      4 May 2018 18:01:04 -0000
@@ -54,7 +54,6 @@ struct psci_softc {
        uint32_t         sc_system_reset;
        uint32_t         sc_cpu_on;
 
-       uint32_t         sc_version;
        uint32_t         sc_smccc_version;
 };
 
@@ -98,6 +97,7 @@ psci_attach(struct device *parent, struc
        struct psci_softc *sc = (struct psci_softc *)self;
        struct fdt_attach_args *faa = aux;
        char method[128];
+       uint32_t version;
 
        if (OF_getprop(faa->fa_node, "method", method, sizeof(method))) {
                if (strcmp(method, "hvc") == 0)
@@ -127,10 +127,10 @@ psci_attach(struct device *parent, struc
 
        psci_sc = sc;
 
-       sc->sc_version = psci_version();
-       printf(": PSCI %d.%d", sc->sc_version >> 16, sc->sc_version & 0xffff);
+       version = psci_version();
+       printf(": PSCI %d.%d", version >> 16, version & 0xffff);
 
-       if (sc->sc_version >= 0x10000) {
+       if (version >= 0x10000) {
                if (psci_features(SMCCC_VERSION) == PSCI_SUCCESS) {
                        sc->sc_smccc_version = smccc_version();
                        printf(", SMCCC %d.%d", sc->sc_smccc_version >> 16,
@@ -165,11 +165,9 @@ psci_powerdown(void)
 }
 
 /*
- * Firmware-based workaround for CVE-2017-5715.  We pick the
- * appropriate mechanism based on the PSCI and SMCCC versions.  We
- * determine whether the workaround is actually needed the first time
- * we are invoked such that we only make the firmware call if we
- * really need to.
+ * Firmware-based workaround for CVE-2017-5715.  We determine whether
+ * the workaround is actually implemented and needed the first time we
+ * are invoked such that we only make the firmware call when appropriate.
  */
 
 void
@@ -178,14 +176,6 @@ psci_flush_bp_none(void)
 }
 
 void
-psci_flush_bp_psci_version(void)
-{
-       struct psci_softc *sc = psci_sc;
-
-       (*sc->sc_callfn)(PSCI_VERSION, 0, 0, 0);
-}
-
-void
 psci_flush_bp_smccc_arch_workaround_1(void)
 {
        struct psci_softc *sc = psci_sc;
@@ -199,32 +189,17 @@ psci_flush_bp(void)
        struct psci_softc *sc = psci_sc;
        struct cpu_info *ci = curcpu();
 
-       /* No PSCI or an old version of PSCI; nothing we can do. */
-       if (sc == NULL || sc->sc_version < 0x10000) {
-               ci->ci_flush_bp = psci_flush_bp_none;
-               return;
-       }
-
-       /*
-        * PSCI 1.0 or later with SMCCC 1.0; invoke PSCI_VERSION and
-        * hope for the best.
-        */
-       if (sc->sc_smccc_version < 0x10001) {
-               ci->ci_flush_bp = psci_flush_bp_psci_version;
-               ci->ci_flush_bp();
-               return;
-       }
-
        /*
-        * SMCCC 1.1 or later; we can actually detect if the
-        * workaround is implemented and needed.
+        * SMCCC 1.1 allows us to detect if the workaround is
+        * implemented and needed.
         */
-       if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) == 0) {
+       if (sc && sc->sc_smccc_version >= 0x10001 &&
+           smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) == 0) {
                /* Workaround implemented and needed. */
                ci->ci_flush_bp = psci_flush_bp_smccc_arch_workaround_1;
                ci->ci_flush_bp();
        } else {
-               /* No workaround needed. */
+               /* Workaround isn't implemented or isn't needed. */
                ci->ci_flush_bp = psci_flush_bp_none;
        }
 }

Reply via email to