From patchwork Mon Jun 24 22:13:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxwell Bland X-Patchwork-Id: 13710194 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1121FC30653 for ; Mon, 24 Jun 2024 22:13:30 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6FDBE6B026D; Mon, 24 Jun 2024 18:13:30 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 6AC646B0284; Mon, 24 Jun 2024 18:13:30 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 4FF8B6B0286; Mon, 24 Jun 2024 18:13:30 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 31A026B026D for ; Mon, 24 Jun 2024 18:13:30 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id C8DB0C13AD for ; Mon, 24 Jun 2024 22:13:29 +0000 (UTC) X-FDA: 82267184538.05.8BB30DC Received: from mx0b-00823401.pphosted.com (mx0b-00823401.pphosted.com [148.163.152.46]) by imf20.hostedemail.com (Postfix) with ESMTP id DD7181C0012 for ; Mon, 24 Jun 2024 22:13:27 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=motorola.com header.s=DKIM202306 header.b="pNJGWhv/"; spf=pass (imf20.hostedemail.com: domain of mbland@motorola.com designates 148.163.152.46 as permitted sender) smtp.mailfrom=mbland@motorola.com; dmarc=pass (policy=none) header.from=motorola.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1719267194; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=xzTdj//kQNkI6INZErfuhFKfWB5d10It9q/1v3tHJuc=; b=B7W1iiDSLbDWy9DeUfgi5d83su9H5Ticgd5uFf1YMZJyYES/GhhEz6xNyOvHQVb1SC2nTz fDXhifz/QRvRbMHvnmh6+PBnCpIcV6xBcQc9Fc+dtoQAzuJbhZZ+rlspI7YOy0cUzjDF9u 6OcN28XW2CDtLZlbReqmHd3pibY6hPE= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1719267194; a=rsa-sha256; cv=none; b=fE27TOFGJseEUeCjFqmqhSgPw0MBifYO+dPLsA5hnqd83lRH/3JD6GJhNv6OB3mInkYwBu Y7j2My2sFTTYzpcrPGWn53UvAWJxq453QVJJYCyyA9C1GWyugTcZmpxV21iibtyR460XbH kG8Wqu8YD0n8ttoPb4i9mH3xn576f3g= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=motorola.com header.s=DKIM202306 header.b="pNJGWhv/"; spf=pass (imf20.hostedemail.com: domain of mbland@motorola.com designates 148.163.152.46 as permitted sender) smtp.mailfrom=mbland@motorola.com; dmarc=pass (policy=none) header.from=motorola.com Received: from pps.filterd (m0355091.ppops.net [127.0.0.1]) by mx0b-00823401.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 45OF2NlO000358; Mon, 24 Jun 2024 22:13:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=motorola.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=DKIM202306; bh=xzTdj//kQNkI6INZErfuhFK fWB5d10It9q/1v3tHJuc=; b=pNJGWhv/zhv7asZpsLEtNusKf0MwwHjM0R79XbK uGcztd9K6rkSBNDqLkVkcFRwa5mL3+Ht3hsTAraUUOQDPhnusLLlcDArY5H1CDnF VUqushrv0bKJWmPBUS8MxN+CVjXCZOBFl5k++gU/0UTytABC/YU38cFYDoOJ0b+p NAAQrdD7u1Lb/AO9oFzMV10XPpcPcmRbFQaIPauSipbp8T0VQ05a8+2SqkvNQ0Gk lbsDzBX/8qDbdK5UARdn8Nk8qvpKuLdylEJvtwU3UzKRgTODrWYd6uovyEfjTpo6 gRQKYPXul7TqcifAkan5C8uXfP6HGtr3h5OORF49gbPqF8w== Received: from va32lpfpp02.lenovo.com ([104.232.228.22]) by mx0b-00823401.pphosted.com (PPS) with ESMTPS id 3yxbqftx79-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Jun 2024 22:13:18 +0000 (GMT) Received: from va32lmmrp02.lenovo.com (va32lmmrp02.mot.com [10.62.176.191]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by va32lpfpp02.lenovo.com (Postfix) with ESMTPS id 4W7Mfj6Y9Qz53xyW; Mon, 24 Jun 2024 22:13:17 +0000 (UTC) Received: from ilclasset02 (ilclasset02.mot.com [100.64.49.13]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: mbland) by va32lmmrp02.lenovo.com (Postfix) with ESMTPSA id 4W7Mfj4N4Fz2VbbV; Mon, 24 Jun 2024 22:13:17 +0000 (UTC) Date: Mon, 24 Jun 2024 17:13:16 -0500 From: Maxwell Bland To: linux-mm@kvack.org Cc: Catalin Marinas , Will Deacon , Jonathan Corbet , Andrew Morton , Ard Biesheuvel , Mark Rutland , Christophe Leroy , Maxwell Bland , Alexandre Ghiti , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 3/6] arm64: table descriptor ptdump support Message-ID: <3z4hwt3fcvscs7zu767vp33tp2mqjor5edfnpgmd2s5p66sg6j@elmhqmeujb5m> References: <2bcb3htsjhepxdybpw2bwot2jnuezl3p5mnj5rhjwgitlsufe7@xzhkyntridw3> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <2bcb3htsjhepxdybpw2bwot2jnuezl3p5mnj5rhjwgitlsufe7@xzhkyntridw3> X-Proofpoint-GUID: T8uRFtf4Po_E6S6YwRNJ3KsUezkw0neA X-Proofpoint-ORIG-GUID: T8uRFtf4Po_E6S6YwRNJ3KsUezkw0neA X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-06-24_19,2024-06-24_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 mlxlogscore=999 lowpriorityscore=0 mlxscore=0 bulkscore=0 spamscore=0 malwarescore=0 suspectscore=0 adultscore=0 impostorscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2406240178 X-Rspamd-Queue-Id: DD7181C0012 X-Stat-Signature: d4sqiwbo3t7in3pe8stx81obncz45utb X-Rspamd-Server: rspam09 X-Rspam-User: X-HE-Tag: 1719267207-468019 X-HE-Meta: U2FsdGVkX1+kHCYV0EfOwxpt1JQ2PnCMWReBSaFeIcxBM1QUgGq7yXIRQfpMW3gmS37+uS7mUgxocvbxhubW4Gj4HgxcBcde4BAkSF5+Xccb42Es2EBSrwDJRJzIsai0bOkLk7TgvWzft3PpFNBJm0IJrh+OCu37S016gry57fmx0x6VYCM6FbnTWZ0fryc62BRTi41jpctRg4MF8K7xc0a8WcLQ4IC8ovs3LbhLxfT79Dx0Y0zl5R2RxHPXECkLNHiMJTfm8u53OufQ9jQM+Tg+UWA+D4/uLXkryYM+eyWje1cz92ORT2ontWWCoWKLLXc5wHuGwImGrT8ZgLLMtYSGXBbQk1L5ZntIgdHay7KFT24QTv9ax0nGtHPfcdkEndBGisxtSE/6IYyYEzjvd7xnTrwG1Rw9N7O1KV0j0Z97Iej40ICuq6gGQNsDdHXHv0Ji4IdAUGdiV6VdOlolryHapnYNrEiOMXMTkNqhhDoJR1O7mPqYbiVJ7rVyFceoxgt7ayJgC+bryZjApqVk7O4h2sb3ZBPMpS5O1qhw52VQ0a2mf7csPF0rVgVj3FOfkBnrKlYdhjq/lAAF+Z0OYSlWUHBl/Zy2/tGwP/Rlb22GiKB9tenqLwDoGDAP3qPg3eA/L/IQ74bZKLHmBeRUs5hMmh1O7vf39GPrNAjHwO4ywJce7yKknWSZVn0hTtYzaEfbzRxya1B9+n+su31S/axShMLGPBTuPuyF6Y8fjJkcYq3kuWsw03Rf6gJLAm1mzNgM9R6k5dNorF+Fe+0qemzv0+d8u9UOxWFMuHuabyZmyyqXMOUClRe12HP25tJKtWz94i6SKbzpm4DgzgZVpoW+pXn+XAKMcSmRiRME/crqCRofe8JJCgsLNVPRUrUNRfv34BbecQVxCslNBXjWfID6q6ubi/dGWg00h6rrFZLHQZhDaXgkekxxSW8hm/YsMYJwgD6nukQqQSJaiCZ UZkca/XN 0tVwOCEQjpN8lLnzMZ5akkT9RsC7k382vd5T2y3s7cQDnfbTOdpexbQRVDeH00KdYVO/EdAq7s24RcXsWjQPTNTLK4EkqFgkgQ+C5pjbg+kE5TCt/DjixOCXZGDvpRd4Cm7/eWxW4hRO3zTi9lj6lXbVbCJaFcU0oToTHwv7yyCTSkfFi9AXusqB+3/w7kt87FIC84qBGQy9lHd2CS9P3I8dBTl8cMtsObTXKmIkZY/y2GTYVfE3oKfsVoUaqouOKFQn7dEwsS5gzKB2okjbo0l8d3+KRtNvNiUuEh9wjx0X2rK9iQRBfhSa7EXyiGMRWn+P6056yLCIChp8= 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: List-Subscribe: List-Unsubscribe: Distinguish between table and block descriptor attribute bitfields, enable the Kconfig option to print table descriptors and intermediate page table entries, and support printing of attributes specific to table descriptors, such as PXNTable. This is useful when debugging protection systems that leverage hierarchical access control. Signed-off-by: Maxwell Bland --- arch/arm64/Kconfig | 1 + arch/arm64/mm/ptdump.c | 142 +++++++++++++++++++++++++++++++---------- 2 files changed, 108 insertions(+), 35 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 5d91259ee7b5..f4c3290160db 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -98,6 +98,7 @@ config ARM64 select ARCH_SUPPORTS_NUMA_BALANCING select ARCH_SUPPORTS_PAGE_TABLE_CHECK select ARCH_SUPPORTS_PER_VMA_LOCK + select ARCH_SUPPORTS_NON_LEAF_PTDUMP select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT select ARCH_WANT_DEFAULT_BPF_JIT diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c index 6986827e0d64..33ca6d182a6a 100644 --- a/arch/arm64/mm/ptdump.c +++ b/arch/arm64/mm/ptdump.c @@ -24,6 +24,7 @@ #include #include #include +#include #define pt_dump_seq_printf(m, fmt, args...) \ @@ -64,7 +65,7 @@ struct prot_bits { const char *clear; }; -static const struct prot_bits pte_bits[] = { +static const struct prot_bits blk_bits[] = { { .mask = PTE_VALID, .val = PTE_VALID, @@ -78,13 +79,13 @@ static const struct prot_bits pte_bits[] = { }, { .mask = PTE_RDONLY, .val = PTE_RDONLY, - .set = "ro", + .set = "RO", .clear = "RW", }, { .mask = PTE_PXN, .val = PTE_PXN, .set = "NX", - .clear = "x ", + .clear = "X ", }, { .mask = PTE_SHARED, .val = PTE_SHARED, @@ -142,44 +143,101 @@ static const struct prot_bits pte_bits[] = { .set = "MEM/NORMAL-TAGGED", } }; +static const size_t num_blk_bits = ARRAY_SIZE(blk_bits); + +static const struct prot_bits tbl_bits[] = { + { + .mask = PTE_VALID, + .val = PTE_VALID, + .set = " ", + .clear = "F", + }, { + .mask = PMD_TABLE_BIT, + .val = PMD_TABLE_BIT, + .set = "TBL", + .clear = " ", + }, { + .mask = PTE_AF, + .val = PTE_AF, + .set = "AF", + .clear = " ", + }, { + .mask = PMD_TABLE_PXN, + .val = PMD_TABLE_PXN, + .set = "NX", + .clear = " ", + }, { + .mask = PMD_TABLE_UXN, + .val = PMD_TABLE_UXN, + .set = "UXN", + .clear = " ", + }, { + .mask = PMD_TABLE_KERN, + .val = PMD_TABLE_KERN, + .set = "KRN", + .clear = " " + }, { + .mask = PMD_TABLE_PRDONLY, + .val = PMD_TABLE_PRDONLY, + .set = "RO", + .clear = "RW" + } +}; +static const size_t num_tbl_bits = ARRAY_SIZE(tbl_bits); struct pg_level { - const struct prot_bits *bits; + const struct prot_bits *blk_bits; + const struct prot_bits *tbl_bits; char name[4]; - int num; u64 mask; + unsigned long size; }; static struct pg_level pg_level[] __ro_after_init = { { /* pgd */ - .name = "PGD", - .bits = pte_bits, - .num = ARRAY_SIZE(pte_bits), + .name = "PGD", + .blk_bits = blk_bits, + .size = PGDIR_SIZE, + .tbl_bits = tbl_bits }, { /* p4d */ - .name = "P4D", - .bits = pte_bits, - .num = ARRAY_SIZE(pte_bits), + .name = "P4D", + .blk_bits = blk_bits, + .size = P4D_SIZE, + .tbl_bits = tbl_bits }, { /* pud */ - .name = "PUD", - .bits = pte_bits, - .num = ARRAY_SIZE(pte_bits), + .name = "PUD", + .blk_bits = blk_bits, + .size = PUD_SIZE, + .tbl_bits = tbl_bits }, { /* pmd */ - .name = "PMD", - .bits = pte_bits, - .num = ARRAY_SIZE(pte_bits), + .name = "PMD", + .blk_bits = blk_bits, + .size = PMD_SIZE, + .tbl_bits = tbl_bits }, { /* pte */ - .name = "PTE", - .bits = pte_bits, - .num = ARRAY_SIZE(pte_bits), + .name = "PTE", + .blk_bits = blk_bits, + .size = PAGE_SIZE, + .tbl_bits = NULL }, }; -static void dump_prot(struct pg_state *st, const struct prot_bits *bits, - size_t num) +static void dump_prot(struct pg_state *st, struct pg_level level) { unsigned i; + const struct prot_bits *bits; + int num_bits; - for (i = 0; i < num; i++, bits++) { + if ((st->current_prot & PTE_TABLE_BIT) == PTE_TABLE_BIT && + level.tbl_bits) { + bits = level.tbl_bits; + num_bits = num_tbl_bits; + } else { + bits = level.blk_bits; + num_bits = num_blk_bits; + } + + for (i = 0; i < num_bits; i++, bits++) { const char *s; if ((st->current_prot & bits->mask) == bits->val) @@ -251,21 +309,30 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, note_prot_wx(st, addr); } - pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx ", - st->start_address, addr); + if (st->start_address == addr) { + if (check_add_overflow(addr, pg_level[st->level].size, + &delta)) + delta = ULONG_MAX - addr + 1; + else + delta = pg_level[st->level].size; + pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx ", + addr, addr + delta); + } else { + delta = (addr - st->start_address); + pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx ", + st->start_address, addr); + } - delta = (addr - st->start_address) >> 10; + delta >>= 10; while (!(delta & 1023) && unit[1]) { delta >>= 10; unit++; } pt_dump_seq_printf(st->seq, "%9lu%c %s", delta, *unit, pg_level[st->level].name); - if (st->current_prot && pg_level[st->level].bits) - dump_prot(st, pg_level[st->level].bits, - pg_level[st->level].num); + if (st->current_prot && pg_level[st->level].blk_bits) + dump_prot(st, pg_level[st->level]); pt_dump_seq_puts(st->seq, "\n"); - if (addr >= st->marker[1].start_address) { st->marker++; pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name); @@ -311,11 +378,16 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info) static void __init ptdump_initialize(void) { unsigned i, j; - - for (i = 0; i < ARRAY_SIZE(pg_level); i++) - if (pg_level[i].bits) - for (j = 0; j < pg_level[i].num; j++) - pg_level[i].mask |= pg_level[i].bits[j].mask; + struct pg_level *level = pg_level; + + for (i = 0; i < ARRAY_SIZE(pg_level); i++, level++) { + if (level->blk_bits) + for (j = 0; j < num_blk_bits; j++) + level->mask |= level->blk_bits[j].mask; + if (level->tbl_bits) + for (j = 0; j < num_tbl_bits; j++) + level->mask |= level->tbl_bits[j].mask; + } } static struct ptdump_info kernel_ptdump_info __ro_after_init = {