summaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-05-11 21:24:41 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2017-06-01 19:54:33 +1000
commita2b05b7aa60e1e9b60faf01dfb1cca35638d1ab1 (patch)
tree8099ff4a321f57dfdbb18eec41d357369c93a0b2 /arch/powerpc
parenta4700a26107241cc7b9ac8528b2c6714ff99983d (diff)
powerpc/64s: Add dt_cpu_ftrs boot time setup option
Provide a dt_cpu_ftrs= cmdline option to disable the dt_cpu_ftrs CPU feature discovery, and fall back to the "cputable" based version. Also allow control of advertising unknown features to userspace and with this parameter, and remove the clunky CONFIG option. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> [mpe: Add explicit early check of bootargs in dt_cpu_ftrs_init()] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/kernel/dt_cpu_ftrs.c57
2 files changed, 48 insertions, 14 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f7c8f9972f61..4a4a05afcaf7 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -391,11 +391,6 @@ config PPC_DT_CPU_FTRS
firmware provides this binding.
If you're not sure say Y.
-config PPC_CPUFEATURES_ENABLE_UNKNOWN
- bool "cpufeatures pass through unknown features to guest/userspace"
- depends on PPC_DT_CPU_FTRS
- default y
-
config HIGHMEM
bool "High memory support"
depends on PPC32
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index fcc7588a96d6..76eebba13a1d 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -8,6 +8,7 @@
#include <linux/export.h>
#include <linux/init.h>
#include <linux/jump_label.h>
+#include <linux/libfdt.h>
#include <linux/memblock.h>
#include <linux/printk.h>
#include <linux/sched.h>
@@ -671,12 +672,24 @@ static struct dt_cpu_feature_match __initdata
{"wait-v3", feat_enable, 0},
};
-/* XXX: how to configure this? Default + boot time? */
-#ifdef CONFIG_PPC_CPUFEATURES_ENABLE_UNKNOWN
-#define CPU_FEATURE_ENABLE_UNKNOWN 1
-#else
-#define CPU_FEATURE_ENABLE_UNKNOWN 0
-#endif
+static bool __initdata using_dt_cpu_ftrs;
+static bool __initdata enable_unknown = true;
+
+static int __init dt_cpu_ftrs_parse(char *str)
+{
+ if (!str)
+ return 0;
+
+ if (!strcmp(str, "off"))
+ using_dt_cpu_ftrs = false;
+ else if (!strcmp(str, "known"))
+ enable_unknown = false;
+ else
+ return 1;
+
+ return 0;
+}
+early_param("dt_cpu_ftrs", dt_cpu_ftrs_parse);
static void __init cpufeatures_setup_start(u32 isa)
{
@@ -707,7 +720,7 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
}
}
- if (!known && CPU_FEATURE_ENABLE_UNKNOWN) {
+ if (!known && enable_unknown) {
if (!feat_try_enable_unknown(f)) {
pr_info("not enabling: %s (unknown and unsupported by kernel)\n",
f->name);
@@ -756,6 +769,26 @@ static void __init cpufeatures_setup_finished(void)
cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features);
}
+static int __init disabled_on_cmdline(void)
+{
+ unsigned long root, chosen;
+ const char *p;
+
+ root = of_get_flat_dt_root();
+ chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
+ if (chosen == -FDT_ERR_NOTFOUND)
+ return false;
+
+ p = of_get_flat_dt_prop(chosen, "bootargs", NULL);
+ if (!p)
+ return false;
+
+ if (strstr(p, "dt_cpu_ftrs=off"))
+ return true;
+
+ return false;
+}
+
static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
int depth, void *data)
{
@@ -766,8 +799,6 @@ static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
return 0;
}
-static bool __initdata using_dt_cpu_ftrs = false;
-
bool __init dt_cpu_ftrs_in_use(void)
{
return using_dt_cpu_ftrs;
@@ -775,6 +806,8 @@ bool __init dt_cpu_ftrs_in_use(void)
bool __init dt_cpu_ftrs_init(void *fdt)
{
+ using_dt_cpu_ftrs = false;
+
/* Setup and verify the FDT, if it fails we just bail */
if (!early_init_dt_verify(fdt))
return false;
@@ -782,6 +815,9 @@ bool __init dt_cpu_ftrs_init(void *fdt)
if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))
return false;
+ if (disabled_on_cmdline())
+ return false;
+
cpufeatures_setup_cpu();
using_dt_cpu_ftrs = true;
@@ -1027,5 +1063,8 @@ static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char
void __init dt_cpu_ftrs_scan(void)
{
+ if (!using_dt_cpu_ftrs)
+ return;
+
of_scan_flat_dt(dt_cpu_ftrs_scan_callback, NULL);
}