Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
"We've got a couple of build fixes when using LLD, a missing TLB
invalidation and a workaround for broken firmware on SoCs with CPUs
that implement MPAM:

- Disable problematic linker assertions for broken versions of LLD

- Work around sporadic link failure with LLD and various randconfig
builds

- Fix missing invalidation in the TLB batching code when reclaim
races with mprotect() and friends

- Add a command-line override for MPAM to allow booting on systems
with broken firmware"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: Add override for MPAM
arm64/mm: Close theoretical race where stale TLB entry remains valid
arm64: Work around convergence issue with LLD linker
arm64: Disable LLD linker ASSERT()s for the time being

+49 -23
+3
Documentation/admin-guide/kernel-parameters.txt
··· 458 458 arm64.nomops [ARM64] Unconditionally disable Memory Copy and Memory 459 459 Set instructions support 460 460 461 + arm64.nompam [ARM64] Unconditionally disable Memory Partitioning And 462 + Monitoring support 463 + 461 464 arm64.nomte [ARM64] Unconditionally disable Memory Tagging Extension 462 465 support 463 466
+10 -14
arch/arm64/include/asm/el2_setup.h
··· 298 298 .Lskip_gcs_\@: 299 299 .endm 300 300 301 - .macro __init_el2_mpam 302 - /* Memory Partitioning And Monitoring: disable EL2 traps */ 303 - mrs x1, id_aa64pfr0_el1 304 - ubfx x0, x1, #ID_AA64PFR0_EL1_MPAM_SHIFT, #4 305 - cbz x0, .Lskip_mpam_\@ // skip if no MPAM 306 - msr_s SYS_MPAM2_EL2, xzr // use the default partition 307 - // and disable lower traps 308 - mrs_s x0, SYS_MPAMIDR_EL1 309 - tbz x0, #MPAMIDR_EL1_HAS_HCR_SHIFT, .Lskip_mpam_\@ // skip if no MPAMHCR reg 310 - msr_s SYS_MPAMHCR_EL2, xzr // clear TRAP_MPAMIDR_EL1 -> EL2 311 - .Lskip_mpam_\@: 312 - .endm 313 - 314 301 /** 315 302 * Initialize EL2 registers to sane values. This should be called early on all 316 303 * cores that were booted in EL2. Note that everything gets initialised as ··· 315 328 __init_el2_stage2 316 329 __init_el2_gicv3 317 330 __init_el2_hstr 318 - __init_el2_mpam 319 331 __init_el2_nvhe_idregs 320 332 __init_el2_cptr 321 333 __init_el2_fgt ··· 361 375 #endif 362 376 363 377 .macro finalise_el2_state 378 + check_override id_aa64pfr0, ID_AA64PFR0_EL1_MPAM_SHIFT, .Linit_mpam_\@, .Lskip_mpam_\@, x1, x2 379 + 380 + .Linit_mpam_\@: 381 + msr_s SYS_MPAM2_EL2, xzr // use the default partition 382 + // and disable lower traps 383 + mrs_s x0, SYS_MPAMIDR_EL1 384 + tbz x0, #MPAMIDR_EL1_HAS_HCR_SHIFT, .Lskip_mpam_\@ // skip if no MPAMHCR reg 385 + msr_s SYS_MPAMHCR_EL2, xzr // clear TRAP_MPAMIDR_EL1 -> EL2 386 + 387 + .Lskip_mpam_\@: 364 388 check_override id_aa64pfr0, ID_AA64PFR0_EL1_SVE_SHIFT, .Linit_sve_\@, .Lskip_sve_\@, x1, x2 365 389 366 390 .Linit_sve_\@: /* SVE register access */
+1 -1
arch/arm64/include/asm/kernel-pgtable.h
··· 58 58 #define INIT_DIR_SIZE (PAGE_SIZE * (EARLY_PAGES(SWAPPER_PGTABLE_LEVELS, KIMAGE_VADDR, _end, EXTRA_PAGE) \ 59 59 + EARLY_SEGMENT_EXTRA_PAGES)) 60 60 61 - #define INIT_IDMAP_DIR_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, KIMAGE_VADDR, _end, 1)) 61 + #define INIT_IDMAP_DIR_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, KIMAGE_VADDR, kimage_limit, 1)) 62 62 #define INIT_IDMAP_DIR_SIZE ((INIT_IDMAP_DIR_PAGES + EARLY_IDMAP_EXTRA_PAGES) * PAGE_SIZE) 63 63 64 64 #define INIT_IDMAP_FDT_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, 0UL, UL(MAX_FDT_SIZE), 1) - 1)
+5 -4
arch/arm64/include/asm/tlbflush.h
··· 323 323 } 324 324 325 325 /* 326 - * If mprotect/munmap/etc occurs during TLB batched flushing, we need to 327 - * synchronise all the TLBI issued with a DSB to avoid the race mentioned in 328 - * flush_tlb_batched_pending(). 326 + * If mprotect/munmap/etc occurs during TLB batched flushing, we need to ensure 327 + * all the previously issued TLBIs targeting mm have completed. But since we 328 + * can be executing on a remote CPU, a DSB cannot guarantee this like it can 329 + * for arch_tlbbatch_flush(). Our only option is to flush the entire mm. 329 330 */ 330 331 static inline void arch_flush_tlb_batched_pending(struct mm_struct *mm) 331 332 { 332 - dsb(ish); 333 + flush_tlb_mm(mm); 333 334 } 334 335 335 336 /*
+5 -2
arch/arm64/kernel/cpufeature.c
··· 1199 1199 cpacr_restore(cpacr); 1200 1200 } 1201 1201 1202 - if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0)) 1202 + if (id_aa64pfr0_mpam(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1))) { 1203 + info->reg_mpamidr = read_cpuid(MPAMIDR_EL1); 1203 1204 init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr); 1205 + } 1204 1206 1205 1207 if (id_aa64pfr1_mte(info->reg_id_aa64pfr1)) 1206 1208 init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid); ··· 1455 1453 cpacr_restore(cpacr); 1456 1454 } 1457 1455 1458 - if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0)) { 1456 + if (id_aa64pfr0_mpam(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1))) { 1457 + info->reg_mpamidr = read_cpuid(MPAMIDR_EL1); 1459 1458 taint |= check_update_ftr_reg(SYS_MPAMIDR_EL1, cpu, 1460 1459 info->reg_mpamidr, boot->reg_mpamidr); 1461 1460 }
+5 -2
arch/arm64/kernel/cpuinfo.c
··· 496 496 if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) 497 497 __cpuinfo_store_cpu_32bit(&info->aarch32); 498 498 499 - if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0)) 500 - info->reg_mpamidr = read_cpuid(MPAMIDR_EL1); 499 + /* 500 + * info->reg_mpamidr deferred to {init,update}_cpu_features because we 501 + * don't want to read it (and trigger a trap on buggy firmware) if 502 + * using an aa64pfr0_el1 override to unconditionally disable MPAM. 503 + */ 501 504 502 505 if (IS_ENABLED(CONFIG_ARM64_SME) && 503 506 id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+17
arch/arm64/kernel/image-vars.h
··· 10 10 #error This file should only be included in vmlinux.lds.S 11 11 #endif 12 12 13 + #if defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 210000 14 + #define ASSERT(...) 15 + #endif 16 + 13 17 #define PI_EXPORT_SYM(sym) \ 14 18 __PI_EXPORT_SYM(sym, __pi_ ## sym, Cannot export BSS symbol sym to startup code) 15 19 #define __PI_EXPORT_SYM(sym, pisym, msg)\ ··· 143 139 #ifdef CONFIG_EFI_ZBOOT 144 140 _kernel_codesize = ABSOLUTE(__inittext_end - _text); 145 141 #endif 142 + 143 + /* 144 + * LLD will occasionally error out with a '__init_end does not converge' error 145 + * if INIT_IDMAP_DIR_SIZE is defined in terms of _end, as this results in a 146 + * circular dependency. Counter this by dimensioning the initial IDMAP page 147 + * tables based on kimage_limit, which is defined such that its value should 148 + * not change as a result of the initdata segment being pushed over a 64k 149 + * segment boundary due to changes in INIT_IDMAP_DIR_SIZE, provided that its 150 + * value doesn't change by more than 2M between linker passes. 151 + */ 152 + kimage_limit = ALIGN(ABSOLUTE(_end + SZ_64K), SZ_2M); 153 + 154 + #undef ASSERT 146 155 147 156 #endif /* __ARM64_KERNEL_IMAGE_VARS_H */
+3
arch/arm64/kernel/pi/idreg-override.c
··· 127 127 .fields = { 128 128 FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT, pfr0_sve_filter), 129 129 FIELD("el0", ID_AA64PFR0_EL1_EL0_SHIFT, NULL), 130 + FIELD("mpam", ID_AA64PFR0_EL1_MPAM_SHIFT, NULL), 130 131 {} 131 132 }, 132 133 }; ··· 155 154 FIELD("gcs", ID_AA64PFR1_EL1_GCS_SHIFT, NULL), 156 155 FIELD("mte", ID_AA64PFR1_EL1_MTE_SHIFT, NULL), 157 156 FIELD("sme", ID_AA64PFR1_EL1_SME_SHIFT, pfr1_sme_filter), 157 + FIELD("mpam_frac", ID_AA64PFR1_EL1_MPAM_frac_SHIFT, NULL), 158 158 {} 159 159 }, 160 160 }; ··· 248 246 { "rodata=off", "arm64_sw.rodataoff=1" }, 249 247 { "arm64.nolva", "id_aa64mmfr2.varange=0" }, 250 248 { "arm64.no32bit_el0", "id_aa64pfr0.el0=1" }, 249 + { "arm64.nompam", "id_aa64pfr0.mpam=0 id_aa64pfr1.mpam_frac=0" }, 251 250 }; 252 251 253 252 static int __init parse_hexdigit(const char *p, u64 *v)