]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - arch/powerpc/platforms/powernv/setup.c
Revert "powerpc/powernv: Increase memory block size to 1GB on radix"
[mirror_ubuntu-bionic-kernel.git] / arch / powerpc / platforms / powernv / setup.c
index 1edfbc1e40f4387b30dd5c0a9491935460feaf92..34e36f91a38e11ea2e3d4cb1e371f34e17b05376 100644 (file)
 #include <asm/kexec.h>
 #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;
+       bool enable;
+
+       /* Default to fallback in case fw-features are not available */
+       type = L1D_FLUSH_FALLBACK;
+
+       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) {
+               init_fw_feat_flags(fw_features);
+               of_node_put(fw_features);
+
+               if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
+                       type = L1D_FLUSH_MTTRIG;
+
+               if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
+                       type = L1D_FLUSH_ORI;
+       }
+
+       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)
 {
        set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
 
+       pnv_setup_rfi_flush();
+       setup_stf_barrier();
+
        /* Initialize SMP */
        pnv_smp_init();
 
@@ -273,15 +362,7 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
 #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
 static unsigned long pnv_memory_block_size(void)
 {
-       /*
-        * We map the kernel linear region with 1GB large pages on radix. For
-        * memory hot unplug to work our memory block size must be at least
-        * this size.
-        */
-       if (radix_enabled())
-               return 1UL * 1024 * 1024 * 1024;
-       else
-               return 256UL * 1024 * 1024;
+       return 256UL * 1024 * 1024;
 }
 #endif