diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-28 09:02:04 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-28 09:02:04 -0700 |
| commit | 9d607ae0f7d629dc068aed5f498e24d3e9875ef1 (patch) | |
| tree | a66740d5e5fa38735a640f41b2e6d30ce9a43a60 /arch | |
| parent | 72ecc30d607f6c8ef8ac0d7b88b0c176a7409367 (diff) | |
| parent | 2bd533739234d79b74afabfece1abfe9c6d52c83 (diff) | |
| download | linux-next-9d607ae0f7d629dc068aed5f498e24d3e9875ef1.tar.gz linux-next-9d607ae0f7d629dc068aed5f498e24d3e9875ef1.zip | |
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Will Deacon:
"A mixture of ptdump, compat and MTE fixes that came in during the
merge window:
- Fix address handling of final memory region in ptdump
- Fix emulation of decrementing load/store multiple from 32-bit task
- Fix SCTLR context-switching for store-only MTE mode
- Fix numerous issues in MTE selftests"
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
selftests/arm64: Add MTE test config fragment
selftests/arm64: Fix MTE prctl TAP plan
selftests/arm64: Treat KSM merge_across_nodes as optional
selftests/arm64: Print missing MTE TAP headers
arm64: compat: Fix decrementing LDM/STM alignment emulation
arm64: process: Fix context switching MTE store-only tag check
KVM: arm64: ptdump: Flush the last region
arm64: ptdump: Make note_page_flush() range aware
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm64/include/asm/processor.h | 2 | ||||
| -rw-r--r-- | arch/arm64/include/asm/ptdump.h | 2 | ||||
| -rw-r--r-- | arch/arm64/kernel/compat_alignment.c | 4 | ||||
| -rw-r--r-- | arch/arm64/kvm/ptdump.c | 11 | ||||
| -rw-r--r-- | arch/arm64/mm/ptdump.c | 14 |
5 files changed, 25 insertions, 8 deletions
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index c2a627f39314..6dfbcacd9ba0 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -264,7 +264,7 @@ static inline void task_set_sve_vl_onexec(struct task_struct *task, #define SCTLR_USER_MASK \ (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | SCTLR_ELx_ENDA | SCTLR_ELx_ENDB | \ - SCTLR_EL1_TCF0_MASK) + SCTLR_EL1_TCF0_MASK | SCTLR_EL1_TCSO0_MASK) static inline void arch_thread_struct_whitelist(unsigned long *offset, unsigned long *size) diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h index 50a195eda8ed..3aa8fa2fcec7 100644 --- a/arch/arm64/include/asm/ptdump.h +++ b/arch/arm64/include/asm/ptdump.h @@ -50,6 +50,8 @@ struct ptdump_pg_state { const struct addr_marker *marker; const struct mm_struct *mm; unsigned long start_address; + /* exclusive end, ULONG_MAX represents an end at 1 << 64 */ + unsigned long end_address; int level; ptval_t current_prot; bool check_wx; diff --git a/arch/arm64/kernel/compat_alignment.c b/arch/arm64/kernel/compat_alignment.c index b68e1d328d4c..9b58d0aa38d2 100644 --- a/arch/arm64/kernel/compat_alignment.c +++ b/arch/arm64/kernel/compat_alignment.c @@ -114,8 +114,8 @@ do_alignment_ldrdstrd(unsigned long addr, u32 instr, struct pt_regs *regs) static int do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs) { - unsigned int rd, rn, nr_regs, regbits; - unsigned long eaddr, newaddr; + unsigned int rd, rn, regbits; + unsigned long eaddr, newaddr, nr_regs; unsigned int val; /* count the number of registers in the mask to be transferred */ diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c index c9140e22abcf..69899797dbad 100644 --- a/arch/arm64/kvm/ptdump.c +++ b/arch/arm64/kvm/ptdump.c @@ -130,7 +130,7 @@ static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm_s2_mmu } st->ipa_marker[0].name = "Guest IPA"; - st->ipa_marker[1].start_address = BIT(pgtable->ia_bits); + st->ipa_marker[1].start_address = ULONG_MAX; st->mmu = mmu; return st; @@ -148,18 +148,21 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *unused) .flags = KVM_PGTABLE_WALK_LEAF, }; + guard(write_lock)(&kvm->mmu_lock); st->parser_state = (struct ptdump_pg_state) { .marker = &st->ipa_marker[0], + .end_address = BIT(mmu->pgt->ia_bits), .level = -1, .pg_level = &st->level[0], .seq = m, }; - write_lock(&kvm->mmu_lock); ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker); - write_unlock(&kvm->mmu_lock); + if (ret) + return ret; + note_page_flush(&st->parser_state.ptdump); - return ret; + return 0; } static int kvm_ptdump_guest_open(struct inode *m, struct file *file) diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c index 5a76c59b5ada..9d9bcb6738f4 100644 --- a/arch/arm64/mm/ptdump.c +++ b/arch/arm64/mm/ptdump.c @@ -278,9 +278,19 @@ void note_page_pgd(struct ptdump_state *pt_st, unsigned long addr, pgd_t pgd) void note_page_flush(struct ptdump_state *pt_st) { + struct ptdump_pg_state *st = container_of(pt_st, struct ptdump_pg_state, ptdump); + unsigned long end = st->end_address; pte_t pte_zero = {0}; - note_page(pt_st, 0, -1, pte_val(pte_zero)); + /* + * Address spaces that end at 1 << 64 have end_address == ULONG_MAX, + * but note_page() expects the exclusive end. In this case adjust end + * to the wraparound value 0. + */ + if (end == ULONG_MAX) + end = 0; + + note_page(pt_st, end, -1, pte_val(pte_zero)); } void ptdump_walk(struct seq_file *s, struct ptdump_info *info) @@ -296,6 +306,7 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info) .marker = info->markers, .mm = info->mm, .pg_level = &kernel_pg_levels[0], + .end_address = end, .level = -1, .ptdump = { .note_page_pte = note_page_pte, @@ -337,6 +348,7 @@ bool ptdump_check_wx(void) { -1, NULL}, }, .pg_level = &kernel_pg_levels[0], + .end_address = ~0UL, .level = -1, .check_wx = true, .ptdump = { |
