]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - arch/powerpc/platforms/powernv/setup.c
Merge tag 'powerpc-4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
[linux.git] / arch / powerpc / platforms / powernv / setup.c
index 092715b9674bb93309b3793ed4ccd2719407e5db..ef8c9ce53a616910d264f4875b9ec72311a110a8 100644 (file)
 #include <asm/smp.h>
 #include <asm/tm.h>
 #include <asm/setup.h>
+#include <asm/security_features.h>
 
 #include "powernv.h"
 
+
+static bool fw_feature_is(const char *state, const char *name,
+                         struct device_node *fw_features)
+{
+       struct device_node *np;
+       bool rc = false;
+
+       np = of_get_child_by_name(fw_features, name);
+       if (np) {
+               rc = of_property_read_bool(np, state);
+               of_node_put(np);
+       }
+
+       return rc;
+}
+
+static void init_fw_feat_flags(struct device_node *np)
+{
+       if (fw_feature_is("enabled", "inst-spec-barrier-ori31,31,0", np))
+               security_ftr_set(SEC_FTR_SPEC_BAR_ORI31);
+
+       if (fw_feature_is("enabled", "fw-bcctrl-serialized", np))
+               security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
+
+       if (fw_feature_is("enabled", "inst-l1d-flush-ori30,30,0", np))
+               security_ftr_set(SEC_FTR_L1D_FLUSH_ORI30);
+
+       if (fw_feature_is("enabled", "inst-l1d-flush-trig2", np))
+               security_ftr_set(SEC_FTR_L1D_FLUSH_TRIG2);
+
+       if (fw_feature_is("enabled", "fw-l1d-thread-split", np))
+               security_ftr_set(SEC_FTR_L1D_THREAD_PRIV);
+
+       if (fw_feature_is("enabled", "fw-count-cache-disabled", np))
+               security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED);
+
+       /*
+        * The features below are enabled by default, so we instead look to see
+        * if firmware has *disabled* them, and clear them if so.
+        */
+       if (fw_feature_is("disabled", "speculation-policy-favor-security", np))
+               security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
+
+       if (fw_feature_is("disabled", "needs-l1d-flush-msr-pr-0-to-1", np))
+               security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
+
+       if (fw_feature_is("disabled", "needs-l1d-flush-msr-hv-1-to-0", np))
+               security_ftr_clear(SEC_FTR_L1D_FLUSH_HV);
+
+       if (fw_feature_is("disabled", "needs-spec-barrier-for-bound-checks", np))
+               security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
+}
+
 static void pnv_setup_rfi_flush(void)
 {
        struct device_node *np, *fw_features;
        enum l1d_flush_type type;
-       int enable;
+       bool enable;
 
        /* Default to fallback in case fw-features are not available */
        type = L1D_FLUSH_FALLBACK;
-       enable = 1;
 
        np = of_find_node_by_name(NULL, "ibm,opal");
        fw_features = of_get_child_by_name(np, "fw-features");
        of_node_put(np);
 
        if (fw_features) {
-               np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2");
-               if (np && of_property_read_bool(np, "enabled"))
-                       type = L1D_FLUSH_MTTRIG;
+               init_fw_feat_flags(fw_features);
+               of_node_put(fw_features);
 
-               of_node_put(np);
+               if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
+                       type = L1D_FLUSH_MTTRIG;
 
-               np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0");
-               if (np && of_property_read_bool(np, "enabled"))
+               if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
                        type = L1D_FLUSH_ORI;
-
-               of_node_put(np);
-
-               /* Enable unless firmware says NOT to */
-               enable = 2;
-               np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0");
-               if (np && of_property_read_bool(np, "disabled"))
-                       enable--;
-
-               of_node_put(np);
-
-               np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1");
-               if (np && of_property_read_bool(np, "disabled"))
-                       enable--;
-
-               np = of_get_child_by_name(fw_features, "speculation-policy-favor-security");
-               if (np && of_property_read_bool(np, "disabled"))
-                       enable = 0;
-
-               of_node_put(np);
-               of_node_put(fw_features);
        }
 
-       setup_rfi_flush(type, enable > 0);
+       enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \
+                (security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)   || \
+                 security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV));
+
+       setup_rfi_flush(type, enable);
 }
 
 static void __init pnv_setup_arch(void)
@@ -166,17 +201,12 @@ static void pnv_prepare_going_down(void)
         */
        opal_event_shutdown();
 
-       /* Soft disable interrupts */
-       local_irq_disable();
+       /* Print flash update message if one is scheduled. */
+       opal_flash_update_print_message();
 
-       /*
-        * Return secondary CPUs to firwmare if a flash update
-        * is pending otherwise we will get all sort of error
-        * messages about CPU being stuck etc.. This will also
-        * have the side effect of hard disabling interrupts so
-        * past this point, the kernel is effectively dead.
-        */
-       opal_flash_term_callback();
+       smp_send_stop();
+
+       hard_irq_disable();
 }
 
 static void  __noreturn pnv_restart(char *cmd)
@@ -258,7 +288,7 @@ static void pnv_kexec_wait_secondaries_down(void)
                        if (i != notified) {
                                printk(KERN_INFO "kexec: waiting for cpu %d "
                                       "(physical %d) to enter OPAL\n",
-                                      i, paca[i].hw_cpu_id);
+                                      i, paca_ptrs[i]->hw_cpu_id);
                                notified = i;
                        }
 
@@ -270,7 +300,7 @@ static void pnv_kexec_wait_secondaries_down(void)
                        if (timeout-- == 0) {
                                printk(KERN_ERR "kexec: timed out waiting for "
                                       "cpu %d (physical %d) to enter OPAL\n",
-                                      i, paca[i].hw_cpu_id);
+                                      i, paca_ptrs[i]->hw_cpu_id);
                                break;
                        }
                }