diff options
-rw-r--r-- | Documentation/admin-guide/kernel-parameters.txt | 9 | ||||
-rw-r--r-- | arch/powerpc/Kconfig | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/dt_cpu_ftrs.c | 57 |
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 | ||
394 | config 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 | |||
399 | config HIGHMEM | 394 | config 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? */ | 675 | static bool __initdata using_dt_cpu_ftrs; |
675 | #ifdef CONFIG_PPC_CPUFEATURES_ENABLE_UNKNOWN | 676 | static bool __initdata enable_unknown = true; |
676 | #define CPU_FEATURE_ENABLE_UNKNOWN 1 | 677 | |
677 | #else | 678 | static 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 | } | ||
692 | early_param("dt_cpu_ftrs", dt_cpu_ftrs_parse); | ||
680 | 693 | ||
681 | static void __init cpufeatures_setup_start(u32 isa) | 694 | static 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 | ||
772 | static 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 | |||
759 | static int __init fdt_find_cpu_features(unsigned long node, const char *uname, | 792 | static 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 | ||
769 | static bool __initdata using_dt_cpu_ftrs = false; | ||
770 | |||
771 | bool __init dt_cpu_ftrs_in_use(void) | 802 | bool __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 | ||
776 | bool __init dt_cpu_ftrs_init(void *fdt) | 807 | bool __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 | ||
1028 | void __init dt_cpu_ftrs_scan(void) | 1064 | void __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 | } |