aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt9
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/kernel/dt_cpu_ftrs.c57
3 files changed, 57 insertions, 14 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 15f79c27748d..0f5c3b4347c6 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -866,6 +866,15 @@
866 866
867 dscc4.setup= [NET] 867 dscc4.setup= [NET]
868 868
869 dt_cpu_ftrs= [PPC]
870 Format: {"off" | "known"}
871 Control how the dt_cpu_ftrs device-tree binding is
872 used for CPU feature discovery and setup (if it
873 exists).
874 off: Do not use it, fall back to legacy cpu table.
875 known: Do not pass through unknown features to guests
876 or userspace, only those that the kernel is aware of.
877
869 dump_apple_properties [X86] 878 dump_apple_properties [X86]
870 Dump name and content of EFI device properties on 879 Dump name and content of EFI device properties on
871 x86 Macs. Useful for driver authors to determine 880 x86 Macs. Useful for driver authors to determine
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
391 firmware provides this binding. 391 firmware provides this binding.
392 If you're not sure say Y. 392 If you're not sure say Y.
393 393
394config PPC_CPUFEATURES_ENABLE_UNKNOWN
395 bool "cpufeatures pass through unknown features to guest/userspace"
396 depends on PPC_DT_CPU_FTRS
397 default y
398
399config HIGHMEM 394config HIGHMEM
400 bool "High memory support" 395 bool "High memory support"
401 depends on PPC32 396 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 @@
8#include <linux/export.h> 8#include <linux/export.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/jump_label.h> 10#include <linux/jump_label.h>
11#include <linux/libfdt.h>
11#include <linux/memblock.h> 12#include <linux/memblock.h>
12#include <linux/printk.h> 13#include <linux/printk.h>
13#include <linux/sched.h> 14#include <linux/sched.h>
@@ -671,12 +672,24 @@ static struct dt_cpu_feature_match __initdata
671 {"wait-v3", feat_enable, 0}, 672 {"wait-v3", feat_enable, 0},
672}; 673};
673 674
674/* XXX: how to configure this? Default + boot time? */ 675static bool __initdata using_dt_cpu_ftrs;
675#ifdef CONFIG_PPC_CPUFEATURES_ENABLE_UNKNOWN 676static bool __initdata enable_unknown = true;
676#define CPU_FEATURE_ENABLE_UNKNOWN 1 677
677#else 678static int __init dt_cpu_ftrs_parse(char *str)
678#define CPU_FEATURE_ENABLE_UNKNOWN 0 679{
679#endif 680 if (!str)
681 return 0;
682
683 if (!strcmp(str, "off"))
684 using_dt_cpu_ftrs = false;
685 else if (!strcmp(str, "known"))
686 enable_unknown = false;
687 else
688 return 1;
689
690 return 0;
691}
692early_param("dt_cpu_ftrs", dt_cpu_ftrs_parse);
680 693
681static void __init cpufeatures_setup_start(u32 isa) 694static void __init cpufeatures_setup_start(u32 isa)
682{ 695{
@@ -707,7 +720,7 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
707 } 720 }
708 } 721 }
709 722
710 if (!known && CPU_FEATURE_ENABLE_UNKNOWN) { 723 if (!known && enable_unknown) {
711 if (!feat_try_enable_unknown(f)) { 724 if (!feat_try_enable_unknown(f)) {
712 pr_info("not enabling: %s (unknown and unsupported by kernel)\n", 725 pr_info("not enabling: %s (unknown and unsupported by kernel)\n",
713 f->name); 726 f->name);
@@ -756,6 +769,26 @@ static void __init cpufeatures_setup_finished(void)
756 cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features); 769 cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features);
757} 770}
758 771
772static int __init disabled_on_cmdline(void)
773{
774 unsigned long root, chosen;
775 const char *p;
776
777 root = of_get_flat_dt_root();
778 chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
779 if (chosen == -FDT_ERR_NOTFOUND)
780 return false;
781
782 p = of_get_flat_dt_prop(chosen, "bootargs", NULL);
783 if (!p)
784 return false;
785
786 if (strstr(p, "dt_cpu_ftrs=off"))
787 return true;
788
789 return false;
790}
791
759static int __init fdt_find_cpu_features(unsigned long node, const char *uname, 792static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
760 int depth, void *data) 793 int depth, void *data)
761{ 794{
@@ -766,8 +799,6 @@ static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
766 return 0; 799 return 0;
767} 800}
768 801
769static bool __initdata using_dt_cpu_ftrs = false;
770
771bool __init dt_cpu_ftrs_in_use(void) 802bool __init dt_cpu_ftrs_in_use(void)
772{ 803{
773 return using_dt_cpu_ftrs; 804 return using_dt_cpu_ftrs;
@@ -775,6 +806,8 @@ bool __init dt_cpu_ftrs_in_use(void)
775 806
776bool __init dt_cpu_ftrs_init(void *fdt) 807bool __init dt_cpu_ftrs_init(void *fdt)
777{ 808{
809 using_dt_cpu_ftrs = false;
810
778 /* Setup and verify the FDT, if it fails we just bail */ 811 /* Setup and verify the FDT, if it fails we just bail */
779 if (!early_init_dt_verify(fdt)) 812 if (!early_init_dt_verify(fdt))
780 return false; 813 return false;
@@ -782,6 +815,9 @@ bool __init dt_cpu_ftrs_init(void *fdt)
782 if (!of_scan_flat_dt(fdt_find_cpu_features, NULL)) 815 if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))
783 return false; 816 return false;
784 817
818 if (disabled_on_cmdline())
819 return false;
820
785 cpufeatures_setup_cpu(); 821 cpufeatures_setup_cpu();
786 822
787 using_dt_cpu_ftrs = true; 823 using_dt_cpu_ftrs = true;
@@ -1027,5 +1063,8 @@ static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char
1027 1063
1028void __init dt_cpu_ftrs_scan(void) 1064void __init dt_cpu_ftrs_scan(void)
1029{ 1065{
1066 if (!using_dt_cpu_ftrs)
1067 return;
1068
1030 of_scan_flat_dt(dt_cpu_ftrs_scan_callback, NULL); 1069 of_scan_flat_dt(dt_cpu_ftrs_scan_callback, NULL);
1031} 1070}