From patchwork Wed Jun 7 12:35:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Stoppa X-Patchwork-Id: 9771483 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DAE8A60364 for ; Wed, 7 Jun 2017 12:38:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5C5A284A6 for ; Wed, 7 Jun 2017 12:38:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BA267284BB; Wed, 7 Jun 2017 12:38:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 0A511284A8 for ; Wed, 7 Jun 2017 12:38:31 +0000 (UTC) Received: (qmail 30308 invoked by uid 550); 7 Jun 2017 12:38:30 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 30287 invoked from network); 7 Jun 2017 12:38:30 -0000 From: Igor Stoppa To: , , CC: , , , , , , , , , , Igor Stoppa Date: Wed, 7 Jun 2017 15:35:04 +0300 Message-ID: <20170607123505.16629-4-igor.stoppa@huawei.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170607123505.16629-1-igor.stoppa@huawei.com> References: <20170607123505.16629-1-igor.stoppa@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.225.51] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090203.5937F3A7.012B, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: f99d48634fe9f6a1d286255b7888589f Subject: [kernel-hardening] [PATCH 3/4] Protectable Memory Allocator - Debug interface X-Virus-Scanned: ClamAV using ClamSMTP Debugfs interface: it creates the file /sys/kernel/debug/pmalloc/pools which exposes statistics about all the pools and memory nodes in use. Signed-off-by: Igor Stoppa --- mm/Kconfig | 11 ++++++ mm/pmalloc.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/mm/Kconfig b/mm/Kconfig index beb7a45..dfbdc07 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -539,6 +539,17 @@ config CMA_AREAS If unsure, leave the default value "7". +config PMALLOC_DEBUG + bool "Protectable Memory Allocator debugging" + depends on DEBUG_KERNEL + default y + help + Debugfs support for dumping information about memory pools. + It shows internal stats: free/used/total space, protection + status, data overhead, etc. + + If unsure, say "y". + config MEM_SOFT_DIRTY bool "Track memory changes" depends on CHECKPOINT_RESTORE && HAVE_ARCH_SOFT_DIRTY && PROC_FS diff --git a/mm/pmalloc.c b/mm/pmalloc.c index 8050dea..09ce7f3 100644 --- a/mm/pmalloc.c +++ b/mm/pmalloc.c @@ -224,3 +224,116 @@ int __init pmalloc_init(void) atomic_set(&pmalloc_data->pools_count, 0); return 0; } + +#ifdef CONFIG_PMALLOC_DEBUG +#include +static struct dentry *pmalloc_root; + +static void *__pmalloc_seq_start(struct seq_file *s, loff_t *pos) +{ + if (*pos) + return NULL; + return pos; +} + +static void *__pmalloc_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + return NULL; +} + +static void __pmalloc_seq_stop(struct seq_file *s, void *v) +{ +} + +static __always_inline +void __seq_printf_node(struct seq_file *s, struct pmalloc_node *node) +{ + unsigned long total_space, node_pages, end_of_node, + used_space, available_space; + int total_words, used_words, available_words; + + used_words = atomic_read(&node->used_words); + total_words = node->total_words; + available_words = total_words - used_words; + used_space = used_words * WORD_SIZE; + total_space = total_words * WORD_SIZE; + available_space = total_space - used_space; + node_pages = (total_space + HEADER_SIZE) / PAGE_SIZE; + end_of_node = total_space + HEADER_SIZE + (unsigned long) node; + seq_printf(s, " - node:\t\t%pK\n", node); + seq_printf(s, " - start of data ptr:\t%pK\n", node->data); + seq_printf(s, " - end of node ptr:\t%pK\n", (void *)end_of_node); + seq_printf(s, " - total words:\t%d\n", total_words); + seq_printf(s, " - used words:\t%d\n", used_words); + seq_printf(s, " - available words:\t%d\n", available_words); + seq_printf(s, " - pages:\t\t%lu\n", node_pages); + seq_printf(s, " - total space:\t%lu\n", total_space); + seq_printf(s, " - used space:\t%lu\n", used_space); + seq_printf(s, " - available space:\t%lu\n", available_space); +} + +static __always_inline +void __seq_printf_pool(struct seq_file *s, struct pmalloc_pool *pool) +{ + struct pmalloc_node *node; + + seq_printf(s, "pool:\t\t\t%pK\n", pool); + seq_printf(s, " - name:\t\t%s\n", pool->name); + seq_printf(s, " - protected:\t\t%u\n", atomic_read(&pool->protected)); + seq_printf(s, " - nodes count:\t\t%u\n", + atomic_read(&pool->nodes_count)); + rcu_read_lock(); + hlist_for_each_entry_rcu(node, &pool->nodes_list_head, nodes_list) + __seq_printf_node(s, node); + rcu_read_unlock(); +} + +static int __pmalloc_seq_show(struct seq_file *s, void *v) +{ + struct pmalloc_pool *pool; + + seq_printf(s, "pools count:\t\t%u\n", + atomic_read(&pmalloc_data->pools_count)); + seq_printf(s, "page size:\t\t%lu\n", PAGE_SIZE); + seq_printf(s, "word size:\t\t%lu\n", WORD_SIZE); + seq_printf(s, "node header size:\t%lu\n", HEADER_SIZE); + rcu_read_lock(); + hlist_for_each_entry_rcu(pool, &pmalloc_data->pools_list_head, + pools_list) + __seq_printf_pool(s, pool); + rcu_read_unlock(); + return 0; +} + +static const struct seq_operations pmalloc_seq_ops = { + .start = __pmalloc_seq_start, + .next = __pmalloc_seq_next, + .stop = __pmalloc_seq_stop, + .show = __pmalloc_seq_show, +}; + +static int __pmalloc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &pmalloc_seq_ops); +} + +static const struct file_operations pmalloc_file_ops = { + .owner = THIS_MODULE, + .open = __pmalloc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + + +static int __init __pmalloc_init_track_pool(void) +{ + struct dentry *de = NULL; + + pmalloc_root = debugfs_create_dir("pmalloc", NULL); + debugfs_create_file("pools", 0644, pmalloc_root, NULL, + &pmalloc_file_ops); + return 0; +} +late_initcall(__pmalloc_init_track_pool); +#endif