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:
"There are some significant fixes in here for FP state corruption,
hardware access/dirty PTE corruption and an erratum workaround for the
Falkor CPU.

I'm hoping that things finally settle down now, but never say never...

Summary:

- Fix FPSIMD context switch regression introduced in -rc2

- Fix ABI break with SVE CPUID register reporting

- Fix use of uninitialised variable

- Fixes to hardware access/dirty management and sanity checking

- CPU erratum workaround for Falkor CPUs

- Fix reporting of writeable+executable mappings

- Fix signal reporting for RAS errors"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: fpsimd: Fix copying of FP state from signal frame into task struct
arm64/sve: Report SVE to userspace via CPUID only if supported
arm64: fix CONFIG_DEBUG_WX address reporting
arm64: fault: avoid send SIGBUS two times
arm64: hw_breakpoint: Use linux/uaccess.h instead of asm/uaccess.h
arm64: Add software workaround for Falkor erratum 1041
arm64: Define cputype macros for Falkor CPU
arm64: mm: Fix false positives in set_pte_at access/dirty race detection
arm64: mm: Fix pte_mkclean, pte_mkdirty semantics
arm64: Initialise high_memory global variable earlier

+64 -28
+1
Documentation/arm64/silicon-errata.txt
··· 75 75 | Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | 76 76 | Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 | 77 77 | Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 | 78 + | Qualcomm Tech. | Falkor v{1,2} | E1041 | QCOM_FALKOR_ERRATUM_1041 |
+11 -1
arch/arm64/Kconfig
··· 557 557 558 558 If unsure, say Y. 559 559 560 - 561 560 config SOCIONEXT_SYNQUACER_PREITS 562 561 bool "Socionext Synquacer: Workaround for GICv3 pre-ITS" 563 562 default y ··· 575 576 a 128kB offset to be applied to the target address in this commands. 576 577 577 578 If unsure, say Y. 579 + 580 + config QCOM_FALKOR_ERRATUM_E1041 581 + bool "Falkor E1041: Speculative instruction fetches might cause errant memory access" 582 + default y 583 + help 584 + Falkor CPU may speculatively fetch instructions from an improper 585 + memory location when MMU translation is changed from SCTLR_ELn[M]=1 586 + to SCTLR_ELn[M]=0. Prefix an ISB instruction to fix the problem. 587 + 588 + If unsure, say Y. 589 + 578 590 endmenu 579 591 580 592
+10
arch/arm64/include/asm/assembler.h
··· 512 512 #endif 513 513 .endm 514 514 515 + /** 516 + * Errata workaround prior to disable MMU. Insert an ISB immediately prior 517 + * to executing the MSR that will change SCTLR_ELn[M] from a value of 1 to 0. 518 + */ 519 + .macro pre_disable_mmu_workaround 520 + #ifdef CONFIG_QCOM_FALKOR_ERRATUM_E1041 521 + isb 522 + #endif 523 + .endm 524 + 515 525 #endif /* __ASM_ASSEMBLER_H */
+3
arch/arm64/include/asm/cpufeature.h
··· 60 60 #define FTR_VISIBLE true /* Feature visible to the user space */ 61 61 #define FTR_HIDDEN false /* Feature is hidden from the user */ 62 62 63 + #define FTR_VISIBLE_IF_IS_ENABLED(config) \ 64 + (IS_ENABLED(config) ? FTR_VISIBLE : FTR_HIDDEN) 65 + 63 66 struct arm64_ftr_bits { 64 67 bool sign; /* Value is signed ? */ 65 68 bool visible;
+2
arch/arm64/include/asm/cputype.h
··· 91 91 #define BRCM_CPU_PART_VULCAN 0x516 92 92 93 93 #define QCOM_CPU_PART_FALKOR_V1 0x800 94 + #define QCOM_CPU_PART_FALKOR 0xC00 94 95 95 96 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) 96 97 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) ··· 100 99 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) 101 100 #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) 102 101 #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) 102 + #define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) 103 103 104 104 #ifndef __ASSEMBLY__ 105 105
+22 -19
arch/arm64/include/asm/pgtable.h
··· 42 42 #include <asm/cmpxchg.h> 43 43 #include <asm/fixmap.h> 44 44 #include <linux/mmdebug.h> 45 + #include <linux/mm_types.h> 46 + #include <linux/sched.h> 45 47 46 48 extern void __pte_error(const char *file, int line, unsigned long val); 47 49 extern void __pmd_error(const char *file, int line, unsigned long val); ··· 151 149 152 150 static inline pte_t pte_mkclean(pte_t pte) 153 151 { 154 - return clear_pte_bit(pte, __pgprot(PTE_DIRTY)); 152 + pte = clear_pte_bit(pte, __pgprot(PTE_DIRTY)); 153 + pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); 154 + 155 + return pte; 155 156 } 156 157 157 158 static inline pte_t pte_mkdirty(pte_t pte) 158 159 { 159 - return set_pte_bit(pte, __pgprot(PTE_DIRTY)); 160 + pte = set_pte_bit(pte, __pgprot(PTE_DIRTY)); 161 + 162 + if (pte_write(pte)) 163 + pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); 164 + 165 + return pte; 160 166 } 161 167 162 168 static inline pte_t pte_mkold(pte_t pte) ··· 217 207 } 218 208 } 219 209 220 - struct mm_struct; 221 - struct vm_area_struct; 222 - 223 210 extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); 224 211 225 212 /* ··· 245 238 * hardware updates of the pte (ptep_set_access_flags safely changes 246 239 * valid ptes without going through an invalid entry). 247 240 */ 248 - if (pte_valid(*ptep) && pte_valid(pte)) { 241 + if (IS_ENABLED(CONFIG_DEBUG_VM) && pte_valid(*ptep) && pte_valid(pte) && 242 + (mm == current->active_mm || atomic_read(&mm->mm_users) > 1)) { 249 243 VM_WARN_ONCE(!pte_young(pte), 250 244 "%s: racy access flag clearing: 0x%016llx -> 0x%016llx", 251 245 __func__, pte_val(*ptep), pte_val(pte)); ··· 649 641 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 650 642 651 643 /* 652 - * ptep_set_wrprotect - mark read-only while preserving the hardware update of 653 - * the Access Flag. 644 + * ptep_set_wrprotect - mark read-only while trasferring potential hardware 645 + * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit. 654 646 */ 655 647 #define __HAVE_ARCH_PTEP_SET_WRPROTECT 656 648 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep) 657 649 { 658 650 pte_t old_pte, pte; 659 651 660 - /* 661 - * ptep_set_wrprotect() is only called on CoW mappings which are 662 - * private (!VM_SHARED) with the pte either read-only (!PTE_WRITE && 663 - * PTE_RDONLY) or writable and software-dirty (PTE_WRITE && 664 - * !PTE_RDONLY && PTE_DIRTY); see is_cow_mapping() and 665 - * protection_map[]. There is no race with the hardware update of the 666 - * dirty state: clearing of PTE_RDONLY when PTE_WRITE (a.k.a. PTE_DBM) 667 - * is set. 668 - */ 669 - VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(*ptep), 670 - "%s: potential race with hardware DBM", __func__); 671 652 pte = READ_ONCE(*ptep); 672 653 do { 673 654 old_pte = pte; 655 + /* 656 + * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY 657 + * clear), set the PTE_DIRTY bit. 658 + */ 659 + if (pte_hw_dirty(pte)) 660 + pte = pte_mkdirty(pte); 674 661 pte = pte_wrprotect(pte); 675 662 pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), 676 663 pte_val(old_pte), pte_val(pte));
+1
arch/arm64/kernel/cpu-reset.S
··· 37 37 mrs x12, sctlr_el1 38 38 ldr x13, =SCTLR_ELx_FLAGS 39 39 bic x12, x12, x13 40 + pre_disable_mmu_workaround 40 41 msr sctlr_el1, x12 41 42 isb 42 43
+2 -1
arch/arm64/kernel/cpufeature.c
··· 145 145 }; 146 146 147 147 static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { 148 - ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0), 148 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), 149 + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0), 149 150 ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0), 150 151 S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI), 151 152 S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI),
+2
arch/arm64/kernel/efi-entry.S
··· 96 96 mrs x0, sctlr_el2 97 97 bic x0, x0, #1 << 0 // clear SCTLR.M 98 98 bic x0, x0, #1 << 2 // clear SCTLR.C 99 + pre_disable_mmu_workaround 99 100 msr sctlr_el2, x0 100 101 isb 101 102 b 2f ··· 104 103 mrs x0, sctlr_el1 105 104 bic x0, x0, #1 << 0 // clear SCTLR.M 106 105 bic x0, x0, #1 << 2 // clear SCTLR.C 106 + pre_disable_mmu_workaround 107 107 msr sctlr_el1, x0 108 108 isb 109 109 2:
+1 -1
arch/arm64/kernel/fpsimd.c
··· 1043 1043 1044 1044 local_bh_disable(); 1045 1045 1046 - current->thread.fpsimd_state = *state; 1046 + current->thread.fpsimd_state.user_fpsimd = state->user_fpsimd; 1047 1047 if (system_supports_sve() && test_thread_flag(TIF_SVE)) 1048 1048 fpsimd_to_sve(current); 1049 1049
+1
arch/arm64/kernel/head.S
··· 750 750 * to take into account by discarding the current kernel mapping and 751 751 * creating a new one. 752 752 */ 753 + pre_disable_mmu_workaround 753 754 msr sctlr_el1, x20 // disable the MMU 754 755 isb 755 756 bl __create_page_tables // recreate kernel mapping
+1 -1
arch/arm64/kernel/hw_breakpoint.c
··· 28 28 #include <linux/perf_event.h> 29 29 #include <linux/ptrace.h> 30 30 #include <linux/smp.h> 31 + #include <linux/uaccess.h> 31 32 32 33 #include <asm/compat.h> 33 34 #include <asm/current.h> ··· 37 36 #include <asm/traps.h> 38 37 #include <asm/cputype.h> 39 38 #include <asm/system_misc.h> 40 - #include <asm/uaccess.h> 41 39 42 40 /* Breakpoint currently in use for each BRP. */ 43 41 static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
+1
arch/arm64/kernel/relocate_kernel.S
··· 45 45 mrs x0, sctlr_el2 46 46 ldr x1, =SCTLR_ELx_FLAGS 47 47 bic x0, x0, x1 48 + pre_disable_mmu_workaround 48 49 msr sctlr_el2, x0 49 50 isb 50 51 1:
+1
arch/arm64/kvm/hyp-init.S
··· 151 151 mrs x5, sctlr_el2 152 152 ldr x6, =SCTLR_ELx_FLAGS 153 153 bic x5, x5, x6 // Clear SCTL_M and etc 154 + pre_disable_mmu_workaround 154 155 msr sctlr_el2, x5 155 156 isb 156 157
+1 -1
arch/arm64/mm/dump.c
··· 389 389 .check_wx = true, 390 390 }; 391 391 392 - walk_pgd(&st, &init_mm, 0); 392 + walk_pgd(&st, &init_mm, VA_START); 393 393 note_page(&st, 0, 0, 0); 394 394 if (st.wx_pages || st.uxn_pages) 395 395 pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UXN pages found\n",
+2 -3
arch/arm64/mm/fault.c
··· 574 574 { 575 575 struct siginfo info; 576 576 const struct fault_info *inf; 577 - int ret = 0; 578 577 579 578 inf = esr_to_fault_info(esr); 580 579 pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n", ··· 588 589 if (interrupts_enabled(regs)) 589 590 nmi_enter(); 590 591 591 - ret = ghes_notify_sea(); 592 + ghes_notify_sea(); 592 593 593 594 if (interrupts_enabled(regs)) 594 595 nmi_exit(); ··· 603 604 info.si_addr = (void __user *)addr; 604 605 arm64_notify_die("", regs, &info, esr); 605 606 606 - return ret; 607 + return 0; 607 608 } 608 609 609 610 static const struct fault_info fault_info[] = {
+2 -1
arch/arm64/mm/init.c
··· 476 476 477 477 reserve_elfcorehdr(); 478 478 479 + high_memory = __va(memblock_end_of_DRAM() - 1) + 1; 480 + 479 481 dma_contiguous_reserve(arm64_dma_phys_limit); 480 482 481 483 memblock_allow_resize(); ··· 504 502 sparse_init(); 505 503 zone_sizes_init(min, max); 506 504 507 - high_memory = __va((max << PAGE_SHIFT) - 1) + 1; 508 505 memblock_dump_all(); 509 506 } 510 507