Skip to content

Commit d45b832

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Will Deacon: "Here's a sizeable batch of Friday the 13th arm64 fixes for -rc4. What could possibly go wrong? The obvious reason we have so much here is because of the holiday season right after the merge window, but we've also brought back an erratum workaround that was previously dropped at the last minute and there's an MTE coredumping fix that strays outside of the arch/arm64 directory. Summary: - Fix PAGE_TABLE_CHECK failures on hugepage splitting path - Fix PSCI encoding of MEM_PROTECT_RANGE function in UAPI header - Fix NULL deref when accessing debugfs node if PSCI is not present - Fix MTE core dumping when VMA list is being updated concurrently - Fix SME signal frame handling when SVE is not implemented by the CPU - Fix asm constraints for cmpxchg_double() to hazard both words - Fix build failure with stack tracer and older versions of Clang - Bring back workaround for Cortex-A715 erratum 2645198" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: Fix build with CC=clang, CONFIG_FTRACE=y and CONFIG_STACK_TRACER=y arm64/mm: Define dummy pud_user_exec() when using 2-level page-table arm64: errata: Workaround possible Cortex-A715 [ESR|FAR]_ELx corruption firmware/psci: Don't register with debugfs if PSCI isn't available firmware/psci: Fix MEM_PROTECT_RANGE function numbers arm64/signal: Always allocate SVE signal frames on SME only systems arm64/signal: Always accept SVE signal frames on SME only systems arm64/sme: Fix context switch for SME only systems arm64: cmpxchg_double*: hazard against entire exchange variable arm64/uprobes: change the uprobe_opcode_t typedef to fix the sparse warning arm64: mte: Avoid the racy walk of the vma list during core dump elfcore: Add a cprm parameter to elf_core_extra_{phdrs,data_size} arm64: mte: Fix double-freeing of the temporary tag storage during coredump arm64: ptrace: Use ARM64_SME to guard the SME register enumerations arm64/mm: add pud_user_exec() check in pud_user_accessible_page() arm64/mm: fix incorrect file_map_count for invalid pmd
2 parents d9fc151 + 68a63a4 commit d45b832

File tree

22 files changed

+147
-59
lines changed

22 files changed

+147
-59
lines changed

Documentation/arm64/silicon-errata.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ stable kernels.
120120
+----------------+-----------------+-----------------+-----------------------------+
121121
| ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 |
122122
+----------------+-----------------+-----------------+-----------------------------+
123+
| ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 |
124+
+----------------+-----------------+-----------------+-----------------------------+
123125
| ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 |
124126
+----------------+-----------------+-----------------+-----------------------------+
125127
| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 |

arch/arm64/Kconfig

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,6 @@ config ARM64
184184
select HAVE_DEBUG_KMEMLEAK
185185
select HAVE_DMA_CONTIGUOUS
186186
select HAVE_DYNAMIC_FTRACE
187-
select HAVE_DYNAMIC_FTRACE_WITH_ARGS \
188-
if $(cc-option,-fpatchable-function-entry=2)
189187
select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
190188
if DYNAMIC_FTRACE_WITH_ARGS
191189
select HAVE_EFFICIENT_UNALIGNED_ACCESS
@@ -972,6 +970,22 @@ config ARM64_ERRATUM_2457168
972970

973971
If unsure, say Y.
974972

973+
config ARM64_ERRATUM_2645198
974+
bool "Cortex-A715: 2645198: Workaround possible [ESR|FAR]_ELx corruption"
975+
default y
976+
help
977+
This option adds the workaround for ARM Cortex-A715 erratum 2645198.
978+
979+
If a Cortex-A715 cpu sees a page mapping permissions change from executable
980+
to non-executable, it may corrupt the ESR_ELx and FAR_ELx registers on the
981+
next instruction abort caused by permission fault.
982+
983+
Only user-space does executable to non-executable permission transition via
984+
mprotect() system call. Workaround the problem by doing a break-before-make
985+
TLB invalidation, for all changes to executable user space mappings.
986+
987+
If unsure, say Y.
988+
975989
config CAVIUM_ERRATUM_22375
976990
bool "Cavium erratum 22375, 24313"
977991
default y

arch/arm64/include/asm/atomic_ll_sc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ __ll_sc__cmpxchg_double##name(unsigned long old1, \
315315
" cbnz %w0, 1b\n" \
316316
" " #mb "\n" \
317317
"2:" \
318-
: "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr) \
318+
: "=&r" (tmp), "=&r" (ret), "+Q" (*(__uint128_t *)ptr) \
319319
: "r" (old1), "r" (old2), "r" (new1), "r" (new2) \
320320
: cl); \
321321
\

arch/arm64/include/asm/atomic_lse.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ __lse__cmpxchg_double##name(unsigned long old1, \
311311
" eor %[old2], %[old2], %[oldval2]\n" \
312312
" orr %[old1], %[old1], %[old2]" \
313313
: [old1] "+&r" (x0), [old2] "+&r" (x1), \
314-
[v] "+Q" (*(unsigned long *)ptr) \
314+
[v] "+Q" (*(__uint128_t *)ptr) \
315315
: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \
316316
[oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \
317317
: cl); \

arch/arm64/include/asm/hugetlb.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ extern pte_t huge_ptep_get(pte_t *ptep);
4949

5050
void __init arm64_hugetlb_cma_reserve(void);
5151

52+
#define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
53+
extern pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
54+
unsigned long addr, pte_t *ptep);
55+
56+
#define huge_ptep_modify_prot_commit huge_ptep_modify_prot_commit
57+
extern void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
58+
unsigned long addr, pte_t *ptep,
59+
pte_t old_pte, pte_t new_pte);
60+
5261
#include <asm-generic/hugetlb.h>
5362

5463
#endif /* __ASM_HUGETLB_H */

arch/arm64/include/asm/pgtable.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
681681
#define pud_leaf(pud) (pud_present(pud) && !pud_table(pud))
682682
#define pud_valid(pud) pte_valid(pud_pte(pud))
683683
#define pud_user(pud) pte_user(pud_pte(pud))
684-
684+
#define pud_user_exec(pud) pte_user_exec(pud_pte(pud))
685685

686686
static inline void set_pud(pud_t *pudp, pud_t pud)
687687
{
@@ -730,6 +730,7 @@ static inline pmd_t *pud_pgtable(pud_t pud)
730730
#else
731731

732732
#define pud_page_paddr(pud) ({ BUILD_BUG(); 0; })
733+
#define pud_user_exec(pud) pud_user(pud) /* Always 0 with folding */
733734

734735
/* Match pmd_offset folding in <asm/generic/pgtable-nopmd.h> */
735736
#define pmd_set_fixmap(addr) NULL
@@ -862,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
862863

863864
static inline bool pmd_user_accessible_page(pmd_t pmd)
864865
{
865-
return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
866+
return pmd_leaf(pmd) && !pmd_present_invalid(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
866867
}
867868

868869
static inline bool pud_user_accessible_page(pud_t pud)
869870
{
870-
return pud_leaf(pud) && pud_user(pud);
871+
return pud_leaf(pud) && (pud_user(pud) || pud_user_exec(pud));
871872
}
872873
#endif
873874

@@ -1093,6 +1094,15 @@ static inline bool pud_sect_supported(void)
10931094
}
10941095

10951096

1097+
#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
1098+
#define ptep_modify_prot_start ptep_modify_prot_start
1099+
extern pte_t ptep_modify_prot_start(struct vm_area_struct *vma,
1100+
unsigned long addr, pte_t *ptep);
1101+
1102+
#define ptep_modify_prot_commit ptep_modify_prot_commit
1103+
extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
1104+
unsigned long addr, pte_t *ptep,
1105+
pte_t old_pte, pte_t new_pte);
10961106
#endif /* !__ASSEMBLY__ */
10971107

10981108
#endif /* __ASM_PGTABLE_H */

arch/arm64/include/asm/uprobes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE
1717
#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES
1818

19-
typedef u32 uprobe_opcode_t;
19+
typedef __le32 uprobe_opcode_t;
2020

2121
struct arch_uprobe_task {
2222
};

arch/arm64/kernel/cpu_errata.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
661661
CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
662662
},
663663
#endif
664+
#ifdef CONFIG_ARM64_ERRATUM_2645198
665+
{
666+
.desc = "ARM erratum 2645198",
667+
.capability = ARM64_WORKAROUND_2645198,
668+
ERRATA_MIDR_ALL_VERSIONS(MIDR_CORTEX_A715)
669+
},
670+
#endif
664671
#ifdef CONFIG_ARM64_ERRATUM_2077057
665672
{
666673
.desc = "ARM erratum 2077057",

arch/arm64/kernel/elfcore.c

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,27 @@
88
#include <asm/cpufeature.h>
99
#include <asm/mte.h>
1010

11-
#define for_each_mte_vma(vmi, vma) \
11+
#define for_each_mte_vma(cprm, i, m) \
1212
if (system_supports_mte()) \
13-
for_each_vma(vmi, vma) \
14-
if (vma->vm_flags & VM_MTE)
13+
for (i = 0, m = cprm->vma_meta; \
14+
i < cprm->vma_count; \
15+
i++, m = cprm->vma_meta + i) \
16+
if (m->flags & VM_MTE)
1517

16-
static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma)
18+
static unsigned long mte_vma_tag_dump_size(struct core_vma_metadata *m)
1719
{
18-
if (vma->vm_flags & VM_DONTDUMP)
19-
return 0;
20-
21-
return vma_pages(vma) * MTE_PAGE_TAG_STORAGE;
20+
return (m->dump_size >> PAGE_SHIFT) * MTE_PAGE_TAG_STORAGE;
2221
}
2322

2423
/* Derived from dump_user_range(); start/end must be page-aligned */
2524
static int mte_dump_tag_range(struct coredump_params *cprm,
26-
unsigned long start, unsigned long end)
25+
unsigned long start, unsigned long len)
2726
{
2827
int ret = 1;
2928
unsigned long addr;
3029
void *tags = NULL;
3130

32-
for (addr = start; addr < end; addr += PAGE_SIZE) {
31+
for (addr = start; addr < start + len; addr += PAGE_SIZE) {
3332
struct page *page = get_dump_page(addr);
3433

3534
/*
@@ -65,7 +64,6 @@ static int mte_dump_tag_range(struct coredump_params *cprm,
6564
mte_save_page_tags(page_address(page), tags);
6665
put_page(page);
6766
if (!dump_emit(cprm, tags, MTE_PAGE_TAG_STORAGE)) {
68-
mte_free_tag_storage(tags);
6967
ret = 0;
7068
break;
7169
}
@@ -77,32 +75,32 @@ static int mte_dump_tag_range(struct coredump_params *cprm,
7775
return ret;
7876
}
7977

80-
Elf_Half elf_core_extra_phdrs(void)
78+
Elf_Half elf_core_extra_phdrs(struct coredump_params *cprm)
8179
{
82-
struct vm_area_struct *vma;
80+
int i;
81+
struct core_vma_metadata *m;
8382
int vma_count = 0;
84-
VMA_ITERATOR(vmi, current->mm, 0);
8583

86-
for_each_mte_vma(vmi, vma)
84+
for_each_mte_vma(cprm, i, m)
8785
vma_count++;
8886

8987
return vma_count;
9088
}
9189

9290
int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
9391
{
94-
struct vm_area_struct *vma;
95-
VMA_ITERATOR(vmi, current->mm, 0);
92+
int i;
93+
struct core_vma_metadata *m;
9694

97-
for_each_mte_vma(vmi, vma) {
95+
for_each_mte_vma(cprm, i, m) {
9896
struct elf_phdr phdr;
9997

10098
phdr.p_type = PT_AARCH64_MEMTAG_MTE;
10199
phdr.p_offset = offset;
102-
phdr.p_vaddr = vma->vm_start;
100+
phdr.p_vaddr = m->start;
103101
phdr.p_paddr = 0;
104-
phdr.p_filesz = mte_vma_tag_dump_size(vma);
105-
phdr.p_memsz = vma->vm_end - vma->vm_start;
102+
phdr.p_filesz = mte_vma_tag_dump_size(m);
103+
phdr.p_memsz = m->end - m->start;
106104
offset += phdr.p_filesz;
107105
phdr.p_flags = 0;
108106
phdr.p_align = 0;
@@ -114,28 +112,25 @@ int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
114112
return 1;
115113
}
116114

117-
size_t elf_core_extra_data_size(void)
115+
size_t elf_core_extra_data_size(struct coredump_params *cprm)
118116
{
119-
struct vm_area_struct *vma;
117+
int i;
118+
struct core_vma_metadata *m;
120119
size_t data_size = 0;
121-
VMA_ITERATOR(vmi, current->mm, 0);
122120

123-
for_each_mte_vma(vmi, vma)
124-
data_size += mte_vma_tag_dump_size(vma);
121+
for_each_mte_vma(cprm, i, m)
122+
data_size += mte_vma_tag_dump_size(m);
125123

126124
return data_size;
127125
}
128126

129127
int elf_core_write_extra_data(struct coredump_params *cprm)
130128
{
131-
struct vm_area_struct *vma;
132-
VMA_ITERATOR(vmi, current->mm, 0);
133-
134-
for_each_mte_vma(vmi, vma) {
135-
if (vma->vm_flags & VM_DONTDUMP)
136-
continue;
129+
int i;
130+
struct core_vma_metadata *m;
137131

138-
if (!mte_dump_tag_range(cprm, vma->vm_start, vma->vm_end))
132+
for_each_mte_vma(cprm, i, m) {
133+
if (!mte_dump_tag_range(cprm, m->start, m->dump_size))
139134
return 0;
140135
}
141136

arch/arm64/kernel/fpsimd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ static void task_fpsimd_load(void)
385385
WARN_ON(!system_supports_fpsimd());
386386
WARN_ON(!have_cpu_fpsimd_context());
387387

388-
if (system_supports_sve()) {
388+
if (system_supports_sve() || system_supports_sme()) {
389389
switch (current->thread.fp_type) {
390390
case FP_STATE_FPSIMD:
391391
/* Stop tracking SVE for this task until next use. */

0 commit comments

Comments
 (0)