From patchwork Fri Apr 22 16:48:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 66465 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp826912qge; Fri, 22 Apr 2016 09:50:21 -0700 (PDT) X-Received: by 10.66.193.202 with SMTP id hq10mr29190365pac.6.1461343821745; Fri, 22 Apr 2016 09:50:21 -0700 (PDT) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id g28si1209285pfg.142.2016.04.22.09.50.21 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Apr 2016 09:50:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ateGk-0002lo-U9; Fri, 22 Apr 2016 16:49:26 +0000 Received: from mail-wm0-x230.google.com ([2a00:1450:400c:c09::230]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ateG4-0001nG-TJ for linux-arm-kernel@lists.infradead.org; Fri, 22 Apr 2016 16:48:46 +0000 Received: by mail-wm0-x230.google.com with SMTP id n3so35828381wmn.0 for ; Fri, 22 Apr 2016 09:48:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qnZydijN1zYAu8CykfzWdiXF6xgG23xthfynsO+uA/I=; b=AOjMl6G2L2/fUyFOfnNTc2sykXm36zQc1dQy67TapXHsO6G4d4oqQAY4C4/qzKua9j JdJzu5busXjmvfBljRNSk4Poa7402u035Yk+j17bPcQMJxIgy+wkbRuFnGrMvMdI+3u8 nTRU3msLkE1cQrjt8Aj7WhujuSzNVuSa/7wEU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qnZydijN1zYAu8CykfzWdiXF6xgG23xthfynsO+uA/I=; b=LlWn1HP/lmVjiF5uVOkN1ZX0xZSkBowxwsjQLoK+2qfQc+Wt+pCTjRD35GQoWYS6pw G7fgvB/cyxct3cBcRirVCfrlJI+8/GvPfIAsJtPUklQLei8ShmDZeb3rkUYmd/TwdQNA Z/BWHU8xntky90B7SBxtVDt/mTcbVm2N7JijBXAJBsvCrPXT9xJPlVwMWC8CVkxgFLs4 3A0WUGlDwQnpAzgj0W3S+fbUB+SYdbsWHwlXu7c3lmEaemFLpKwKCb6Ay1XqvVlsT2Aj f0oCLO65XYV3cZa4PUlnvghLQxhHu0z/gfMzsYefa3vCGJ8Plen4+VSD/heZ+2mH8ykz EfBw== X-Gm-Message-State: AOPr4FUcC296nFbq5IMN/EKnFqWN3nTORrGOSaqtsYgFA9OsopZ2KkRYbmhu3DtyCu9+og4g X-Received: by 10.28.10.7 with SMTP id 7mr4675048wmk.43.1461343703272; Fri, 22 Apr 2016 09:48:23 -0700 (PDT) Received: from localhost.localdomain ([195.55.142.58]) by smtp.gmail.com with ESMTPSA id h8sm4256015wmd.2.2016.04.22.09.48.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 22 Apr 2016 09:48:22 -0700 (PDT) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, linux-efi@vger.kernel.org, mark.rutland@arm.com, catalin.marinas@arm.com, linux@arm.linux.org.uk Subject: [PATCH v2 5/6] arm: mm: dump: make page table dumping reusable Date: Fri, 22 Apr 2016 18:48:07 +0200 Message-Id: <1461343688-8552-6-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1461343688-8552-1-git-send-email-ard.biesheuvel@linaro.org> References: <1461343688-8552-1-git-send-email-ard.biesheuvel@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160422_094845_294012_0B5E09C4 X-CRM114-Status: GOOD ( 21.58 ) X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2a00:1450:400c:c09:0:0:0:230 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: will.deacon@arm.com, keescook@chromium.org, Ard Biesheuvel MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org For debugging purposes, it would be nice if we could export page tables other than the swapper_pg_dir to userspace. To enable this, this patch refactors the ARM page table dumping code such that multiple tables may be registered with the framework, and exported under debugfs. (this is a port of Mark Rutland's arm64 patch that does the same) Signed-off-by: Ard Biesheuvel --- arch/arm/include/asm/ptdump.h | 44 ++++++++++++++ arch/arm/mm/dump.c | 60 ++++++++++++-------- 2 files changed, 81 insertions(+), 23 deletions(-) -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel diff --git a/arch/arm/include/asm/ptdump.h b/arch/arm/include/asm/ptdump.h new file mode 100644 index 000000000000..2df5737b2cc7 --- /dev/null +++ b/arch/arm/include/asm/ptdump.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __ASM_PTDUMP_H +#define __ASM_PTDUMP_H + +#ifdef CONFIG_ARM_PTDUMP + +#include + +struct addr_marker { + unsigned long start_address; + char *name; +}; + +struct ptdump_info { + struct mm_struct *mm; + const struct addr_marker *markers; + unsigned long base_addr; + unsigned long max_addr; +}; + +int ptdump_register(struct ptdump_info *info, const char *name); + +#else +static inline int ptdump_register(struct ptdump_info *info, const char *name) +{ + return 0; +} +#endif /* CONFIG_ARM_PTDUMP */ + +#endif /* __ASM_PTDUMP_H */ diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c index 9fe8e241335c..0c1ff61440aa 100644 --- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -19,11 +19,7 @@ #include #include - -struct addr_marker { - unsigned long start_address; - const char *name; -}; +#include static struct addr_marker address_markers[] = { { MODULES_VADDR, "Modules" }, @@ -266,7 +262,8 @@ static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start) } } -static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) +static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start, + unsigned long max) { pmd_t *pmd = pmd_offset(pud, 0); unsigned long addr; @@ -274,6 +271,8 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) for (i = 0; i < PTRS_PER_PMD; i++, pmd++) { addr = start + i * PMD_SIZE; + if (addr > max) + break; if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd)) note_page(st, addr, 3, pmd_val(*pmd)); else @@ -284,7 +283,8 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) } } -static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) +static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start, + unsigned long max) { pud_t *pud = pud_offset(pgd, 0); unsigned long addr; @@ -292,46 +292,51 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) for (i = 0; i < PTRS_PER_PUD; i++, pud++) { addr = start + i * PUD_SIZE; + if (addr > max) + break; if (!pud_none(*pud)) { - walk_pmd(st, pud, addr); + walk_pmd(st, pud, addr, max); } else { note_page(st, addr, 2, pud_val(*pud)); } } } -static void walk_pgd(struct seq_file *m) +static void walk_pgd(struct pg_state *st, struct mm_struct *mm, unsigned long max) { - pgd_t *pgd = swapper_pg_dir; - struct pg_state st; + pgd_t *pgd = pgd_offset(mm, 0UL); unsigned long addr; unsigned i; - memset(&st, 0, sizeof(st)); - st.seq = m; - st.marker = address_markers; - for (i = 0; i < PTRS_PER_PGD; i++, pgd++) { addr = i * PGDIR_SIZE; + if (addr > max) + break; if (!pgd_none(*pgd)) { - walk_pud(&st, pgd, addr); + walk_pud(st, pgd, addr, max); } else { - note_page(&st, addr, 1, pgd_val(*pgd)); + note_page(st, addr, 1, pgd_val(*pgd)); } } - note_page(&st, 0, 0, 0); + note_page(st, 0, 0, 0); } static int ptdump_show(struct seq_file *m, void *v) { - walk_pgd(m); + struct ptdump_info *info = m->private; + struct pg_state st = { + .seq = m, + .marker = info->markers, + }; + + walk_pgd(&st, info->mm, info->max_addr); return 0; } static int ptdump_open(struct inode *inode, struct file *file) { - return single_open(file, ptdump_show, NULL); + return single_open(file, ptdump_show, inode->i_private); } static const struct file_operations ptdump_fops = { @@ -341,7 +346,7 @@ static const struct file_operations ptdump_fops = { .release = single_release, }; -static int ptdump_init(void) +int ptdump_register(struct ptdump_info *info, const char *name) { struct dentry *pe; unsigned i, j; @@ -353,8 +358,17 @@ static int ptdump_init(void) address_markers[2].start_address = VMALLOC_START; - pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, - &ptdump_fops); + pe = debugfs_create_file(name, 0400, NULL, info, &ptdump_fops); return pe ? 0 : -ENOMEM; } + +static struct ptdump_info kernel_ptdump_info = { + .mm = &init_mm, + .markers = address_markers, +}; + +static int ptdump_init(void) +{ + return ptdump_register(&kernel_ptdump_info, "kernel_page_tables"); +} __initcall(ptdump_init);