From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 708FFCA9ECF for ; Fri, 1 Nov 2019 14:10:57 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 339C1217D9 for ; Fri, 1 Nov 2019 14:10:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 339C1217D9 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id DCABA6B0285; Fri, 1 Nov 2019 10:10:56 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id D54E76B0286; Fri, 1 Nov 2019 10:10:56 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C20806B0287; Fri, 1 Nov 2019 10:10:56 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0023.hostedemail.com [216.40.44.23]) by kanga.kvack.org (Postfix) with ESMTP id 971116B0285 for ; Fri, 1 Nov 2019 10:10:56 -0400 (EDT) Received: from smtpin10.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id F077583F0 for ; Fri, 1 Nov 2019 14:10:55 +0000 (UTC) X-FDA: 76107894870.10.anger59_4242fda74f65d X-HE-Tag: anger59_4242fda74f65d X-Filterd-Recvd-Size: 12118 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf43.hostedemail.com (Postfix) with ESMTP for ; Fri, 1 Nov 2019 14:10:55 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DD0507CD; Fri, 1 Nov 2019 07:10:54 -0700 (PDT) Received: from e112269-lin.cambridge.arm.com (e112269-lin.cambridge.arm.com [10.1.194.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5280D3F718; Fri, 1 Nov 2019 07:10:52 -0700 (PDT) From: Steven Price To: Andrew Morton , linux-mm@kvack.org Cc: Steven Price , Andy Lutomirski , Ard Biesheuvel , Arnd Bergmann , Borislav Petkov , Catalin Marinas , Dave Hansen , Ingo Molnar , James Morse , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Peter Zijlstra , Thomas Gleixner , Will Deacon , x86@kernel.org, "H. Peter Anvin" , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Mark Rutland , "Liang, Kan" Subject: [PATCH v15 21/23] arm64: mm: Convert mm/dump.c to use walk_page_range() Date: Fri, 1 Nov 2019 14:09:40 +0000 Message-Id: <20191101140942.51554-22-steven.price@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101140942.51554-1-steven.price@arm.com> References: <20191101140942.51554-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Now walk_page_range() can walk kernel page tables, we can switch the arm64 ptdump code over to using it, simplifying the code. Reviewed-by: Catalin Marinas Signed-off-by: Steven Price --- arch/arm64/Kconfig | 1 + arch/arm64/Kconfig.debug | 19 +---- arch/arm64/include/asm/ptdump.h | 8 +- arch/arm64/mm/Makefile | 4 +- arch/arm64/mm/dump.c | 117 ++++++++++------------------- arch/arm64/mm/mmu.c | 4 +- arch/arm64/mm/ptdump_debugfs.c | 2 +- drivers/firmware/efi/arm-runtime.c | 2 +- 8 files changed, 50 insertions(+), 107 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 41a9b4257b72..0f6ad8dabd77 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -104,6 +104,7 @@ config ARM64 select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW_LEVEL select GENERIC_PCI_IOMAP + select GENERIC_PTDUMP select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD select GENERIC_STRNCPY_FROM_USER diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index cf09010d825f..1c906d932d6b 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug @@ -1,22 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only =20 -config ARM64_PTDUMP_CORE - def_bool n - -config ARM64_PTDUMP_DEBUGFS - bool "Export kernel pagetable layout to userspace via debugfs" - depends on DEBUG_KERNEL - select ARM64_PTDUMP_CORE - select DEBUG_FS - help - Say Y here if you want to show the kernel pagetable layout in a - debugfs file. This information is only useful for kernel developers - who are working in architecture specific areas of the kernel. - It is probably not a good idea to enable this feature in a production - kernel. - - If in doubt, say N. - config PID_IN_CONTEXTIDR bool "Write the current PID to the CONTEXTIDR register" help @@ -42,7 +25,7 @@ config ARM64_RANDOMIZE_TEXT_OFFSET =20 config DEBUG_WX bool "Warn on W+X mappings at boot" - select ARM64_PTDUMP_CORE + select PTDUMP_CORE ---help--- Generate a warning if any W+X mappings are found at boot. =20 diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptd= ump.h index 0b8e7269ec82..38187f74e089 100644 --- a/arch/arm64/include/asm/ptdump.h +++ b/arch/arm64/include/asm/ptdump.h @@ -5,7 +5,7 @@ #ifndef __ASM_PTDUMP_H #define __ASM_PTDUMP_H =20 -#ifdef CONFIG_ARM64_PTDUMP_CORE +#ifdef CONFIG_PTDUMP_CORE =20 #include #include @@ -21,15 +21,15 @@ struct ptdump_info { unsigned long base_addr; }; =20 -void ptdump_walk_pgd(struct seq_file *s, struct ptdump_info *info); -#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS +void ptdump_walk(struct seq_file *s, struct ptdump_info *info); +#ifdef CONFIG_PTDUMP_DEBUGFS void ptdump_debugfs_register(struct ptdump_info *info, const char *name)= ; #else static inline void ptdump_debugfs_register(struct ptdump_info *info, const char *name) { } #endif void ptdump_check_wx(void); -#endif /* CONFIG_ARM64_PTDUMP_CORE */ +#endif /* CONFIG_PTDUMP_CORE */ =20 #ifdef CONFIG_DEBUG_WX #define debug_checkwx() ptdump_check_wx() diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile index 849c1df3d214..d91030f0ffee 100644 --- a/arch/arm64/mm/Makefile +++ b/arch/arm64/mm/Makefile @@ -4,8 +4,8 @@ obj-y :=3D dma-mapping.o extable.o fault.o init.o \ ioremap.o mmap.o pgd.o mmu.o \ context.o proc.o pageattr.o obj-$(CONFIG_HUGETLB_PAGE) +=3D hugetlbpage.o -obj-$(CONFIG_ARM64_PTDUMP_CORE) +=3D dump.o -obj-$(CONFIG_ARM64_PTDUMP_DEBUGFS) +=3D ptdump_debugfs.o +obj-$(CONFIG_PTDUMP_CORE) +=3D dump.o +obj-$(CONFIG_PTDUMP_DEBUGFS) +=3D ptdump_debugfs.o obj-$(CONFIG_NUMA) +=3D numa.o obj-$(CONFIG_DEBUG_VIRTUAL) +=3D physaddr.o KASAN_SANITIZE_physaddr.o +=3D n diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c index 93f9f77582ae..9d9b740a86d2 100644 --- a/arch/arm64/mm/dump.c +++ b/arch/arm64/mm/dump.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include =20 @@ -75,10 +76,11 @@ static struct addr_marker address_markers[] =3D { * dumps out a description of the range. */ struct pg_state { + struct ptdump_state ptdump; struct seq_file *seq; const struct addr_marker *marker; unsigned long start_address; - unsigned level; + int level; u64 current_prot; bool check_wx; unsigned long wx_pages; @@ -178,6 +180,10 @@ static struct pg_level pg_level[] =3D { .name =3D "PGD", .bits =3D pte_bits, .num =3D ARRAY_SIZE(pte_bits), + }, { /* p4d */ + .name =3D "P4D", + .bits =3D pte_bits, + .num =3D ARRAY_SIZE(pte_bits), }, { /* pud */ .name =3D (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD", .bits =3D pte_bits, @@ -240,11 +246,15 @@ static void note_prot_wx(struct pg_state *st, unsig= ned long addr) st->wx_pages +=3D (addr - st->start_address) / PAGE_SIZE; } =20 -static void note_page(struct pg_state *st, unsigned long addr, unsigned = level, - u64 val) +static void note_page(struct ptdump_state *pt_st, unsigned long addr, in= t level, + unsigned long val) { + struct pg_state *st =3D container_of(pt_st, struct pg_state, ptdump); static const char units[] =3D "KMGTPE"; - u64 prot =3D val & pg_level[level].mask; + u64 prot =3D 0; + + if (level >=3D 0) + prot =3D val & pg_level[level].mask; =20 if (!st->level) { st->level =3D level; @@ -292,85 +302,27 @@ static void note_page(struct pg_state *st, unsigned= long addr, unsigned level, =20 } =20 -static void walk_pte(struct pg_state *st, pmd_t *pmdp, unsigned long sta= rt, - unsigned long end) -{ - unsigned long addr =3D start; - pte_t *ptep =3D pte_offset_kernel(pmdp, start); - - do { - note_page(st, addr, 4, READ_ONCE(pte_val(*ptep))); - } while (ptep++, addr +=3D PAGE_SIZE, addr !=3D end); -} - -static void walk_pmd(struct pg_state *st, pud_t *pudp, unsigned long sta= rt, - unsigned long end) -{ - unsigned long next, addr =3D start; - pmd_t *pmdp =3D pmd_offset(pudp, start); - - do { - pmd_t pmd =3D READ_ONCE(*pmdp); - next =3D pmd_addr_end(addr, end); - - if (pmd_none(pmd) || pmd_sect(pmd)) { - note_page(st, addr, 3, pmd_val(pmd)); - } else { - BUG_ON(pmd_bad(pmd)); - walk_pte(st, pmdp, addr, next); - } - } while (pmdp++, addr =3D next, addr !=3D end); -} - -static void walk_pud(struct pg_state *st, pgd_t *pgdp, unsigned long sta= rt, - unsigned long end) +void ptdump_walk(struct seq_file *s, struct ptdump_info *info) { - unsigned long next, addr =3D start; - pud_t *pudp =3D pud_offset(pgdp, start); - - do { - pud_t pud =3D READ_ONCE(*pudp); - next =3D pud_addr_end(addr, end); - - if (pud_none(pud) || pud_sect(pud)) { - note_page(st, addr, 2, pud_val(pud)); - } else { - BUG_ON(pud_bad(pud)); - walk_pmd(st, pudp, addr, next); - } - } while (pudp++, addr =3D next, addr !=3D end); -} + unsigned long end =3D ~0UL; + struct pg_state st; =20 -static void walk_pgd(struct pg_state *st, struct mm_struct *mm, - unsigned long start) -{ - unsigned long end =3D (start < TASK_SIZE_64) ? TASK_SIZE_64 : 0; - unsigned long next, addr =3D start; - pgd_t *pgdp =3D pgd_offset(mm, start); - - do { - pgd_t pgd =3D READ_ONCE(*pgdp); - next =3D pgd_addr_end(addr, end); - - if (pgd_none(pgd)) { - note_page(st, addr, 1, pgd_val(pgd)); - } else { - BUG_ON(pgd_bad(pgd)); - walk_pud(st, pgdp, addr, next); - } - } while (pgdp++, addr =3D next, addr !=3D end); -} + if (info->base_addr < TASK_SIZE_64) + end =3D TASK_SIZE_64; =20 -void ptdump_walk_pgd(struct seq_file *m, struct ptdump_info *info) -{ - struct pg_state st =3D { - .seq =3D m, + st =3D (struct pg_state){ + .seq =3D s, .marker =3D info->markers, + .ptdump =3D { + .note_page =3D note_page, + .range =3D (struct ptdump_range[]){ + {info->base_addr, end}, + {0, 0} + } + } }; =20 - walk_pgd(&st, info->mm, info->base_addr); - - note_page(&st, 0, 0, 0); + ptdump_walk_pgd(&st.ptdump, info->mm); } =20 static void ptdump_initialize(void) @@ -398,10 +350,17 @@ void ptdump_check_wx(void) { -1, NULL}, }, .check_wx =3D true, + .ptdump =3D { + .note_page =3D note_page, + .range =3D (struct ptdump_range[]) { + {PAGE_OFFSET, ~0UL}, + {0, 0} + } + } }; =20 - walk_pgd(&st, &init_mm, PAGE_OFFSET); - note_page(&st, 0, 0, 0); + ptdump_walk_pgd(&st.ptdump, &init_mm); + if (st.wx_pages || st.uxn_pages) pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UX= N pages found\n", st.wx_pages, st.uxn_pages); diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 60c929f3683b..6f12951c8052 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -944,13 +944,13 @@ int __init arch_ioremap_pud_supported(void) * SW table walks can't handle removal of intermediate entries. */ return IS_ENABLED(CONFIG_ARM64_4K_PAGES) && - !IS_ENABLED(CONFIG_ARM64_PTDUMP_DEBUGFS); + !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); } =20 int __init arch_ioremap_pmd_supported(void) { /* See arch_ioremap_pud_supported() */ - return !IS_ENABLED(CONFIG_ARM64_PTDUMP_DEBUGFS); + return !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS); } =20 int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot) diff --git a/arch/arm64/mm/ptdump_debugfs.c b/arch/arm64/mm/ptdump_debugf= s.c index 064163f25592..1f2eae3e988b 100644 --- a/arch/arm64/mm/ptdump_debugfs.c +++ b/arch/arm64/mm/ptdump_debugfs.c @@ -7,7 +7,7 @@ static int ptdump_show(struct seq_file *m, void *v) { struct ptdump_info *info =3D m->private; - ptdump_walk_pgd(m, info); + ptdump_walk(m, info); return 0; } DEFINE_SHOW_ATTRIBUTE(ptdump); diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/ar= m-runtime.c index e2ac5fa5531b..1283685f9c20 100644 --- a/drivers/firmware/efi/arm-runtime.c +++ b/drivers/firmware/efi/arm-runtime.c @@ -27,7 +27,7 @@ =20 extern u64 efi_system_table; =20 -#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS +#if defined(CONFIG_PTDUMP_DEBUGFS) && defined(CONFIG_ARM64) #include =20 static struct ptdump_info efi_ptdump_info =3D { --=20 2.20.1