Pull arm64 fixes from Will Deacon: - Fix kexec and hibernation when using 5-level page-table configuration - Remove references to non-existent SF8MM4 and SF8MM8 ID register fields, hooking up hwcaps for the FPRCVT, F8MM4 and F8MM8 fields instead - Drop unused .ARM.attributes ELF sections - Fix array indexing when probing CPU cache topology from firmware - Fix potential use-after-free in AMU initialisation code - Work around broken GTDT entries by tolerating excessively large timer arrays - Force use of Rust's "softfloat" target to avoid a threatening warning about the NEON target feature - Typo fix in GCS documentation and removal of duplicate Kconfig select * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: rust: clean Rust 1.85.0 warning using softfloat target arm64: Add missing registrations of hwcaps ACPI: GTDT: Relax sanity checking on Platform Timers array count arm64: amu: Delay allocating cpumask for AMU FIE support arm64: cacheinfo: Avoid out-of-bounds write to cacheinfo array arm64: Handle .ARM.attributes section in linker scripts arm64/hwcap: Remove stray references to SF8MMx arm64/gcs: Fix documentation for HWCAP arm64: Kconfig: Remove selecting replaced HAVE_FUNCTION_GRAPH_RETVAL arm64: Fix 5-level paging support in kexec/hibernate trampoline
Unified · Split
| @@ -37,7 +37,7 @@ intended to be exhaustive. · 36 unmodified lines | ||
| 37 | 37 | shadow stacks rather than GCS. |
| 38 | 38 | |
| 39 | 39 | * Support for GCS is reported to userspace via HWCAP_GCS in the aux vector |
| 40 | − AT_HWCAP2 entry. | |
| 40 | + AT_HWCAP entry. | |
| 41 | 41 | |
| 42 | 42 | * GCS is enabled per thread. While there is support for disabling GCS |
| 43 | 43 | at runtime this should be done with great care. |
| @@ -225,7 +225,6 @@ config ARM64 · 224 unmodified lines | ||
| 225 | 225 | select HAVE_FUNCTION_ERROR_INJECTION |
| 226 | 226 | select HAVE_FUNCTION_GRAPH_FREGS |
| 227 | 227 | select HAVE_FUNCTION_GRAPH_TRACER |
| 228 | − select HAVE_FUNCTION_GRAPH_RETVAL | |
| 229 | 228 | select HAVE_GCC_PLUGINS |
| 230 | 229 | select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && \ |
| 231 | 230 | HW_PERF_EVENTS && HAVE_PERF_EVENTS_NMI |
| @@ -48,7 +48,11 @@ KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU) \ · 47 unmodified lines | ||
| 48 | 48 | KBUILD_CFLAGS += $(call cc-disable-warning, psabi) |
| 49 | 49 | KBUILD_AFLAGS += $(compat_vdso) |
| 50 | 50 | |
| 51 | +ifeq ($(call test-ge, $(CONFIG_RUSTC_VERSION), 108500),y) | |
| 52 | +KBUILD_RUSTFLAGS += --target=aarch64-unknown-none-softfloat | |
| 53 | +else | |
| 51 | 54 | KBUILD_RUSTFLAGS += --target=aarch64-unknown-none -Ctarget-feature="-neon" |
| 55 | +endif | |
| 52 | 56 | |
| 53 | 57 | KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) |
| 54 | 58 | KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) |
| @@ -101,16 +101,18 @@ int populate_cache_leaves(unsigned int cpu) · 100 unmodified lines | ||
| 101 | 101 | unsigned int level, idx; |
| 102 | 102 | enum cache_type type; |
| 103 | 103 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); |
| 104 | − struct cacheinfo *this_leaf = this_cpu_ci->info_list; | |
| 104 | + struct cacheinfo *infos = this_cpu_ci->info_list; | |
| 105 | 105 | |
| 106 | 106 | for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && |
| 107 | − idx < this_cpu_ci->num_leaves; idx++, level++) { | |
| 107 | + idx < this_cpu_ci->num_leaves; level++) { | |
| 108 | 108 | type = get_cache_type(level); |
| 109 | 109 | if (type == CACHE_TYPE_SEPARATE) { |
| 110 | − ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); | |
| 111 | − ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); | |
| 110 | + if (idx + 1 >= this_cpu_ci->num_leaves) | |
| 111 | + break; | |
| 112 | + ci_leaf_init(&infos[idx++], CACHE_TYPE_DATA, level); | |
| 113 | + ci_leaf_init(&infos[idx++], CACHE_TYPE_INST, level); | |
| 112 | 114 | } else { |
| 113 | − ci_leaf_init(this_leaf++, type, level); | |
| 115 | + ci_leaf_init(&infos[idx++], type, level); | |
| 114 | 116 | } |
| 115 | 117 | } |
| 116 | 118 | return 0; |
| @@ -3091,6 +3091,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { · 3090 unmodified lines | ||
| 3091 | 3091 | HWCAP_CAP(ID_AA64ISAR0_EL1, TS, FLAGM, CAP_HWCAP, KERNEL_HWCAP_FLAGM), |
| 3092 | 3092 | HWCAP_CAP(ID_AA64ISAR0_EL1, TS, FLAGM2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2), |
| 3093 | 3093 | HWCAP_CAP(ID_AA64ISAR0_EL1, RNDR, IMP, CAP_HWCAP, KERNEL_HWCAP_RNG), |
| 3094 | + HWCAP_CAP(ID_AA64ISAR3_EL1, FPRCVT, IMP, CAP_HWCAP, KERNEL_HWCAP_FPRCVT), | |
| 3094 | 3095 | HWCAP_CAP(ID_AA64PFR0_EL1, FP, IMP, CAP_HWCAP, KERNEL_HWCAP_FP), |
| 3095 | 3096 | HWCAP_CAP(ID_AA64PFR0_EL1, FP, FP16, CAP_HWCAP, KERNEL_HWCAP_FPHP), |
| 3096 | 3097 | HWCAP_CAP(ID_AA64PFR0_EL1, AdvSIMD, IMP, CAP_HWCAP, KERNEL_HWCAP_ASIMD), |
| @@ -3180,8 +3181,6 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { · 83 unmodified lines | ||
| 3180 | 3181 | HWCAP_CAP(ID_AA64SMFR0_EL1, SF8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8FMA), |
| 3181 | 3182 | HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP4), |
| 3182 | 3183 | HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP2), |
| 3183 | − HWCAP_CAP(ID_AA64SMFR0_EL1, SF8MM8, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8MM8), | |
| 3184 | − HWCAP_CAP(ID_AA64SMFR0_EL1, SF8MM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8MM4), | |
| 3185 | 3184 | HWCAP_CAP(ID_AA64SMFR0_EL1, SBitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SBITPERM), |
| 3186 | 3185 | HWCAP_CAP(ID_AA64SMFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_AES), |
| 3187 | 3186 | HWCAP_CAP(ID_AA64SMFR0_EL1, SFEXPA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SFEXPA), |
| @@ -3192,6 +3191,8 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { · 4 unmodified lines | ||
| 3192 | 3191 | HWCAP_CAP(ID_AA64FPFR0_EL1, F8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_F8FMA), |
| 3193 | 3192 | HWCAP_CAP(ID_AA64FPFR0_EL1, F8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_F8DP4), |
| 3194 | 3193 | HWCAP_CAP(ID_AA64FPFR0_EL1, F8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_F8DP2), |
| 3194 | + HWCAP_CAP(ID_AA64FPFR0_EL1, F8MM8, IMP, CAP_HWCAP, KERNEL_HWCAP_F8MM8), | |
| 3195 | + HWCAP_CAP(ID_AA64FPFR0_EL1, F8MM4, IMP, CAP_HWCAP, KERNEL_HWCAP_F8MM4), | |
| 3195 | 3196 | HWCAP_CAP(ID_AA64FPFR0_EL1, F8E4M3, IMP, CAP_HWCAP, KERNEL_HWCAP_F8E4M3), |
| 3196 | 3197 | HWCAP_CAP(ID_AA64FPFR0_EL1, F8E5M2, IMP, CAP_HWCAP, KERNEL_HWCAP_F8E5M2), |
| 3197 | 3198 | #ifdef CONFIG_ARM64_POE |
| @@ -194,12 +194,19 @@ static void amu_fie_setup(const struct cpumask *cpus) · 193 unmodified lines | ||
| 194 | 194 | int cpu; |
| 195 | 195 | |
| 196 | 196 | /* We are already set since the last insmod of cpufreq driver */ |
| 197 | − if (unlikely(cpumask_subset(cpus, amu_fie_cpus))) | |
| 197 | + if (cpumask_available(amu_fie_cpus) && | |
| 198 | + unlikely(cpumask_subset(cpus, amu_fie_cpus))) | |
| 198 | 199 | return; |
| 199 | 200 | |
| 200 | − for_each_cpu(cpu, cpus) { | |
| 201 | + for_each_cpu(cpu, cpus) | |
| 201 | 202 | if (!freq_counters_valid(cpu)) |
| 202 | 203 | return; |
| 204 | + | |
| 205 | + if (!cpumask_available(amu_fie_cpus) && | |
| 206 | + !zalloc_cpumask_var(&amu_fie_cpus, GFP_KERNEL)) { | |
| 207 | + WARN_ONCE(1, "Failed to allocate FIE cpumask for CPUs[%*pbl]\n", | |
| 208 | + cpumask_pr_args(cpus)); | |
| 209 | + return; | |
| 203 | 210 | } |
| 204 | 211 | |
| 205 | 212 | cpumask_or(amu_fie_cpus, amu_fie_cpus, cpus); |
| @@ -237,17 +244,8 @@ static struct notifier_block init_amu_fie_notifier = { · 31 unmodified lines | ||
| 237 | 244 | |
| 238 | 245 | static int __init init_amu_fie(void) |
| 239 | 246 | { |
| 240 | − int ret; | |
| 241 | − | |
| 242 | − if (!zalloc_cpumask_var(&amu_fie_cpus, GFP_KERNEL)) | |
| 243 | − return -ENOMEM; | |
| 244 | − | |
| 245 | − ret = cpufreq_register_notifier(&init_amu_fie_notifier, | |
| 247 | + return cpufreq_register_notifier(&init_amu_fie_notifier, | |
| 246 | 248 | CPUFREQ_POLICY_NOTIFIER); |
| 247 | − if (ret) | |
| 248 | − free_cpumask_var(amu_fie_cpus); | |
| 249 | − | |
| 250 | − return ret; | |
| 251 | 249 | } |
| 252 | 250 | core_initcall(init_amu_fie); |
| 253 | 251 | |
| @@ -41,6 +41,7 @@ SECTIONS · 40 unmodified lines | ||
| 41 | 41 | */ |
| 42 | 42 | /DISCARD/ : { |
| 43 | 43 | *(.note.GNU-stack .note.gnu.property) |
| 44 | + *(.ARM.attributes) | |
| 44 | 45 | } |
| 45 | 46 | .note : { *(.note.*) } :text :note |
| 46 | 47 | |
| @@ -162,6 +162,7 @@ SECTIONS · 161 unmodified lines | ||
| 162 | 162 | /DISCARD/ : { |
| 163 | 163 | *(.interp .dynamic) |
| 164 | 164 | *(.dynsym .dynstr .hash .gnu.hash) |
| 165 | + *(.ARM.attributes) | |
| 165 | 166 | } |
| 166 | 167 | |
| 167 | 168 | . = KIMAGE_VADDR; |
| @@ -162,6 +162,13 @@ static int copy_p4d(struct trans_pgd_info *info, pgd_t *dst_pgdp, · 161 unmodified lines | ||
| 162 | 162 | unsigned long next; |
| 163 | 163 | unsigned long addr = start; |
| 164 | 164 | |
| 165 | + if (pgd_none(READ_ONCE(*dst_pgdp))) { | |
| 166 | + dst_p4dp = trans_alloc(info); | |
| 167 | + if (!dst_p4dp) | |
| 168 | + return -ENOMEM; | |
| 169 | + pgd_populate(NULL, dst_pgdp, dst_p4dp); | |
| 170 | + } | |
| 171 | + | |
| 165 | 172 | dst_p4dp = p4d_offset(dst_pgdp, start); |
| 166 | 173 | src_p4dp = p4d_offset(src_pgdp, start); |
| 167 | 174 | do { |
| @@ -163,7 +163,7 @@ int __init acpi_gtdt_init(struct acpi_table_header *table, · 162 unmodified lines | ||
| 163 | 163 | { |
| 164 | 164 | void *platform_timer; |
| 165 | 165 | struct acpi_table_gtdt *gtdt; |
| 166 | − int cnt = 0; | |
| 166 | + u32 cnt = 0; | |
| 167 | 167 | |
| 168 | 168 | gtdt = container_of(table, struct acpi_table_gtdt, header); |
| 169 | 169 | acpi_gtdt_desc.gtdt = gtdt; |
| @@ -188,13 +188,17 @@ int __init acpi_gtdt_init(struct acpi_table_header *table, · 18 unmodified lines | ||
| 188 | 188 | cnt++; |
| 189 | 189 | |
| 190 | 190 | if (cnt != gtdt->platform_timer_count) { |
| 191 | + cnt = min(cnt, gtdt->platform_timer_count); | |
| 192 | + pr_err(FW_BUG "limiting Platform Timer count to %d\n", cnt); | |
| 193 | + } | |
| 194 | + | |
| 195 | + if (!cnt) { | |
| 191 | 196 | acpi_gtdt_desc.platform_timer = NULL; |
| 192 | − pr_err(FW_BUG "invalid timer data.\n"); | |
| 193 | − return -EINVAL; | |
| 197 | + return 0; | |
| 194 | 198 | } |
| 195 | 199 | |
| 196 | 200 | if (platform_timer_count) |
| 197 | − *platform_timer_count = gtdt->platform_timer_count; | |
| 201 | + *platform_timer_count = cnt; | |
| 198 | 202 | |
| 199 | 203 | return 0; |
| 200 | 204 | } |