@@ -107,6 +107,24 @@ DECLARE_BITMAP(boot_capabilities, ARM64_NPATCHABLE);
107
107
bool arm64_use_ng_mappings = false;
108
108
EXPORT_SYMBOL (arm64_use_ng_mappings );
109
109
110
+ /*
111
+ * Permit PER_LINUX32 and execve() of 32-bit binaries even if not all CPUs
112
+ * support it?
113
+ */
114
+ static bool __read_mostly allow_mismatched_32bit_el0 ;
115
+
116
+ /*
117
+ * Static branch enabled only if allow_mismatched_32bit_el0 is set and we have
118
+ * seen at least one CPU capable of 32-bit EL0.
119
+ */
120
+ DEFINE_STATIC_KEY_FALSE (arm64_mismatched_32bit_el0 );
121
+
122
+ /*
123
+ * Mask of CPUs supporting 32-bit EL0.
124
+ * Only valid if arm64_mismatched_32bit_el0 is enabled.
125
+ */
126
+ static cpumask_var_t cpu_32bit_el0_mask __cpumask_var_read_mostly ;
127
+
110
128
/*
111
129
* Flag to indicate if we have computed the system wide
112
130
* capabilities based on the boot time active CPUs. This
@@ -775,7 +793,7 @@ static void __init sort_ftr_regs(void)
775
793
* Any bits that are not covered by an arm64_ftr_bits entry are considered
776
794
* RES0 for the system-wide value, and must strictly match.
777
795
*/
778
- static void __init init_cpu_ftr_reg (u32 sys_reg , u64 new )
796
+ static void init_cpu_ftr_reg (u32 sys_reg , u64 new )
779
797
{
780
798
u64 val = 0 ;
781
799
u64 strict_mask = ~0x0ULL ;
@@ -871,7 +889,7 @@ static void __init init_cpu_hwcaps_indirect_list(void)
871
889
872
890
static void __init setup_boot_cpu_capabilities (void );
873
891
874
- static void __init init_32bit_cpu_features (struct cpuinfo_32bit * info )
892
+ static void init_32bit_cpu_features (struct cpuinfo_32bit * info )
875
893
{
876
894
init_cpu_ftr_reg (SYS_ID_DFR0_EL1 , info -> reg_id_dfr0 );
877
895
init_cpu_ftr_reg (SYS_ID_DFR1_EL1 , info -> reg_id_dfr1 );
@@ -990,6 +1008,22 @@ static void relax_cpu_ftr_reg(u32 sys_id, int field)
990
1008
WARN_ON (!ftrp -> width );
991
1009
}
992
1010
1011
+ static void lazy_init_32bit_cpu_features (struct cpuinfo_arm64 * info ,
1012
+ struct cpuinfo_arm64 * boot )
1013
+ {
1014
+ static bool boot_cpu_32bit_regs_overridden = false;
1015
+
1016
+ if (!allow_mismatched_32bit_el0 || boot_cpu_32bit_regs_overridden )
1017
+ return ;
1018
+
1019
+ if (id_aa64pfr0_32bit_el0 (boot -> reg_id_aa64pfr0 ))
1020
+ return ;
1021
+
1022
+ boot -> aarch32 = info -> aarch32 ;
1023
+ init_32bit_cpu_features (& boot -> aarch32 );
1024
+ boot_cpu_32bit_regs_overridden = true;
1025
+ }
1026
+
993
1027
static int update_32bit_cpu_features (int cpu , struct cpuinfo_32bit * info ,
994
1028
struct cpuinfo_32bit * boot )
995
1029
{
@@ -1161,6 +1195,7 @@ void update_cpu_features(int cpu,
1161
1195
* (e.g. SYS_ID_AA64PFR0_EL1), so we call it last.
1162
1196
*/
1163
1197
if (id_aa64pfr0_32bit_el0 (info -> reg_id_aa64pfr0 )) {
1198
+ lazy_init_32bit_cpu_features (info , boot );
1164
1199
taint |= update_32bit_cpu_features (cpu , & info -> aarch32 ,
1165
1200
& boot -> aarch32 );
1166
1201
}
@@ -1273,6 +1308,28 @@ has_cpuid_feature(const struct arm64_cpu_capabilities *entry, int scope)
1273
1308
return feature_matches (val , entry );
1274
1309
}
1275
1310
1311
+ const struct cpumask * system_32bit_el0_cpumask (void )
1312
+ {
1313
+ if (!system_supports_32bit_el0 ())
1314
+ return cpu_none_mask ;
1315
+
1316
+ if (static_branch_unlikely (& arm64_mismatched_32bit_el0 ))
1317
+ return cpu_32bit_el0_mask ;
1318
+
1319
+ return cpu_possible_mask ;
1320
+ }
1321
+
1322
+ static bool has_32bit_el0 (const struct arm64_cpu_capabilities * entry , int scope )
1323
+ {
1324
+ if (!has_cpuid_feature (entry , scope ))
1325
+ return allow_mismatched_32bit_el0 ;
1326
+
1327
+ if (scope == SCOPE_SYSTEM )
1328
+ pr_info ("detected: 32-bit EL0 Support\n" );
1329
+
1330
+ return true;
1331
+ }
1332
+
1276
1333
static bool has_useable_gicv3_cpuif (const struct arm64_cpu_capabilities * entry , int scope )
1277
1334
{
1278
1335
bool has_sre ;
@@ -1891,10 +1948,9 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
1891
1948
.cpu_enable = cpu_copy_el2regs ,
1892
1949
},
1893
1950
{
1894
- .desc = "32-bit EL0 Support" ,
1895
- .capability = ARM64_HAS_32BIT_EL0 ,
1951
+ .capability = ARM64_HAS_32BIT_EL0_DO_NOT_USE ,
1896
1952
.type = ARM64_CPUCAP_SYSTEM_FEATURE ,
1897
- .matches = has_cpuid_feature ,
1953
+ .matches = has_32bit_el0 ,
1898
1954
.sys_reg = SYS_ID_AA64PFR0_EL1 ,
1899
1955
.sign = FTR_UNSIGNED ,
1900
1956
.field_pos = ID_AA64PFR0_EL0_SHIFT ,
@@ -2403,7 +2459,7 @@ static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = {
2403
2459
{},
2404
2460
};
2405
2461
2406
- static void __init cap_set_elf_hwcap (const struct arm64_cpu_capabilities * cap )
2462
+ static void cap_set_elf_hwcap (const struct arm64_cpu_capabilities * cap )
2407
2463
{
2408
2464
switch (cap -> hwcap_type ) {
2409
2465
case CAP_HWCAP :
@@ -2448,7 +2504,7 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap)
2448
2504
return rc ;
2449
2505
}
2450
2506
2451
- static void __init setup_elf_hwcaps (const struct arm64_cpu_capabilities * hwcaps )
2507
+ static void setup_elf_hwcaps (const struct arm64_cpu_capabilities * hwcaps )
2452
2508
{
2453
2509
/* We support emulation of accesses to CPU ID feature registers */
2454
2510
cpu_set_named_feature (CPUID );
@@ -2623,7 +2679,7 @@ static void check_early_cpu_features(void)
2623
2679
}
2624
2680
2625
2681
static void
2626
- verify_local_elf_hwcaps (const struct arm64_cpu_capabilities * caps )
2682
+ __verify_local_elf_hwcaps (const struct arm64_cpu_capabilities * caps )
2627
2683
{
2628
2684
2629
2685
for (; caps -> matches ; caps ++ )
@@ -2634,6 +2690,14 @@ verify_local_elf_hwcaps(const struct arm64_cpu_capabilities *caps)
2634
2690
}
2635
2691
}
2636
2692
2693
+ static void verify_local_elf_hwcaps (void )
2694
+ {
2695
+ __verify_local_elf_hwcaps (arm64_elf_hwcaps );
2696
+
2697
+ if (id_aa64pfr0_32bit_el0 (read_cpuid (ID_AA64PFR0_EL1 )))
2698
+ __verify_local_elf_hwcaps (compat_elf_hwcaps );
2699
+ }
2700
+
2637
2701
static void verify_sve_features (void )
2638
2702
{
2639
2703
u64 safe_zcr = read_sanitised_ftr_reg (SYS_ZCR_EL1 );
@@ -2698,11 +2762,7 @@ static void verify_local_cpu_capabilities(void)
2698
2762
* on all secondary CPUs.
2699
2763
*/
2700
2764
verify_local_cpu_caps (SCOPE_ALL & ~SCOPE_BOOT_CPU );
2701
-
2702
- verify_local_elf_hwcaps (arm64_elf_hwcaps );
2703
-
2704
- if (system_supports_32bit_el0 ())
2705
- verify_local_elf_hwcaps (compat_elf_hwcaps );
2765
+ verify_local_elf_hwcaps ();
2706
2766
2707
2767
if (system_supports_sve ())
2708
2768
verify_sve_features ();
@@ -2837,6 +2897,34 @@ void __init setup_cpu_features(void)
2837
2897
ARCH_DMA_MINALIGN );
2838
2898
}
2839
2899
2900
+ static int enable_mismatched_32bit_el0 (unsigned int cpu )
2901
+ {
2902
+ struct cpuinfo_arm64 * info = & per_cpu (cpu_data , cpu );
2903
+ bool cpu_32bit = id_aa64pfr0_32bit_el0 (info -> reg_id_aa64pfr0 );
2904
+
2905
+ if (cpu_32bit ) {
2906
+ cpumask_set_cpu (cpu , cpu_32bit_el0_mask );
2907
+ static_branch_enable_cpuslocked (& arm64_mismatched_32bit_el0 );
2908
+ setup_elf_hwcaps (compat_elf_hwcaps );
2909
+ }
2910
+
2911
+ return 0 ;
2912
+ }
2913
+
2914
+ static int __init init_32bit_el0_mask (void )
2915
+ {
2916
+ if (!allow_mismatched_32bit_el0 )
2917
+ return 0 ;
2918
+
2919
+ if (!zalloc_cpumask_var (& cpu_32bit_el0_mask , GFP_KERNEL ))
2920
+ return - ENOMEM ;
2921
+
2922
+ return cpuhp_setup_state (CPUHP_AP_ONLINE_DYN ,
2923
+ "arm64/mismatched_32bit_el0:online" ,
2924
+ enable_mismatched_32bit_el0 , NULL );
2925
+ }
2926
+ subsys_initcall_sync (init_32bit_el0_mask );
2927
+
2840
2928
static void __maybe_unused cpu_enable_cnp (struct arm64_cpu_capabilities const * cap )
2841
2929
{
2842
2930
cpu_replace_ttbr1 (lm_alias (swapper_pg_dir ));
0 commit comments