From patchwork Wed Jul 25 23:59:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544939 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8545C1822 for ; Wed, 25 Jul 2018 23:59:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6EA2E2A9AC for ; Wed, 25 Jul 2018 23:59:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 62FBC2A9CE; Wed, 25 Jul 2018 23:59:34 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 067BE2A9AC for ; Wed, 25 Jul 2018 23:59:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728485AbeGZBNd (ORCPT ); Wed, 25 Jul 2018 21:13:33 -0400 Received: from mail-pl0-f65.google.com ([209.85.160.65]:34132 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728339AbeGZBNd (ORCPT ); Wed, 25 Jul 2018 21:13:33 -0400 Received: by mail-pl0-f65.google.com with SMTP id f6-v6so3959557plo.1 for ; Wed, 25 Jul 2018 16:59:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uFyUSqGZcwUpvs/8kOWqA1xeN7gtaJ5Do2y1aq/Opn0=; b=qMJsK+nbeiwj3QxjU0RFGknPmtGyvXTJg274hVG1APprnfzdkWAz78Q8181S3Lb07+ 6P8wW2uhErXsPU0V5z2puQyAzRJVxgw3GdtpFTN2hA5SbgC9rDJ1AGR7ksWyz+eTC0Se 5UdYr0aFoDYt+XxYYqwZSh8/TFUQqOnFCgRdXJ7/ZvOTLw7D8b02SvBI7OlCpS5qXnjB dD1ZbfWb9ih8/F2siqgekm+cRRgcWwgGnOR7SSWNP1AE76q5+0c6/Ciexlst9/v1WnBc j4AADh2ysFMKjRBqpVLdRDMENC4WQhd+ToOmkX/yaie9JRmlWi3tMvRstaJqtv/cfLz7 D76w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=uFyUSqGZcwUpvs/8kOWqA1xeN7gtaJ5Do2y1aq/Opn0=; b=LZW71j7WucEsV6XUgj2su8BIydLmRUrgV7aQf4oUjfDp3GBx5EhrCxloeVjzIPcqNH 4dFL4Gs1VYm/Y+K00icvqru6Ru0/A9VkULmakBiNW0MMA5hFEVVbTjr3B88gnhWDiZ5M KFYG7YJm1YUhrYxYtv7n9JoHYwqPW7J5EACChzNO4escNOT9HnVRmDz5PJc4bvifNP8n NsuygGfjGbq78WTYgkV2dAMIG+gXgdywJIn9/FZdOSG/t2MYM/Hwv36cJUWQ35CFYZ4V kmgdKnujqnBGzm69SSYfiXKA0LMlYh/YZS2hwSutuGFxESjHsHHbvt6kJ5bf8qnGxi/M oryQ== X-Gm-Message-State: AOUpUlG8nvpsMI7UUIKJqAn+FlCK7K8utqm27ALFJyhjdBv3xEONSjcc rjmu9MBnH5Bo9vPJxcGDK+qDVg== X-Google-Smtp-Source: AAOMgpfUVbLhe2D3DOr0xi0xnNoeC8Pj2sFhNWZYRHSG2OzwyRqbIujvX7WGWYrAM0yqBxQp1m3TFQ== X-Received: by 2002:a17:902:e005:: with SMTP id ca5-v6mr22929578plb.224.1532563168526; Wed, 25 Jul 2018 16:59:28 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:28 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 1/9] proc/kcore: don't grab lock for kclist_add() Date: Wed, 25 Jul 2018 16:59:12 -0700 Message-Id: <12f4b3dc5254547d12cb6669c45c533e647511fb.1532563124.git.osandov@fb.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval kclist_add() is only called at init time, so there's no point in grabbing any locks. We're also going to replace the rwlock with a rwsem, which we don't want to try grabbing during early boot. While we're here, mark kclist_add() with __init so that we'll get a warning if it's called from non-init code. Reviewed-by: Andrew Morton Signed-off-by: Omar Sandoval --- fs/proc/kcore.c | 7 +++---- include/linux/kcore.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 66c373230e60..b0b9a76f28d6 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -62,16 +62,15 @@ static LIST_HEAD(kclist_head); static DEFINE_RWLOCK(kclist_lock); static int kcore_need_update = 1; -void -kclist_add(struct kcore_list *new, void *addr, size_t size, int type) +/* This doesn't grab kclist_lock, so it should only be used at init time. */ +void __init kclist_add(struct kcore_list *new, void *addr, size_t size, + int type) { new->addr = (unsigned long)addr; new->size = size; new->type = type; - write_lock(&kclist_lock); list_add_tail(&new->list, &kclist_head); - write_unlock(&kclist_lock); } static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) diff --git a/include/linux/kcore.h b/include/linux/kcore.h index 8de55e4b5ee9..c20f296438fb 100644 --- a/include/linux/kcore.h +++ b/include/linux/kcore.h @@ -35,7 +35,7 @@ struct vmcoredd_node { }; #ifdef CONFIG_PROC_KCORE -extern void kclist_add(struct kcore_list *, void *, size_t, int type); +void __init kclist_add(struct kcore_list *, void *, size_t, int type); #else static inline void kclist_add(struct kcore_list *new, void *addr, size_t size, int type) From patchwork Wed Jul 25 23:59:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544955 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5E2FC112E for ; Thu, 26 Jul 2018 00:00:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E2432A9D4 for ; Thu, 26 Jul 2018 00:00:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4228B2A9D9; Thu, 26 Jul 2018 00:00:29 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DDCBD2A9D4 for ; Thu, 26 Jul 2018 00:00:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728825AbeGZBOb (ORCPT ); Wed, 25 Jul 2018 21:14:31 -0400 Received: from mail-pl0-f67.google.com ([209.85.160.67]:34134 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728339AbeGZBNe (ORCPT ); Wed, 25 Jul 2018 21:13:34 -0400 Received: by mail-pl0-f67.google.com with SMTP id f6-v6so3959574plo.1 for ; Wed, 25 Jul 2018 16:59:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=16w7KIxIKq7DVWU2jRPaeALdZ2xcgpzjcsj3qPwpVus=; b=H8lv7CQz9Qhs+Me4ITN+H1NBrrZKWUlWKl8IttdoHw9pbcu7/y5Y/ecyBmvtF1RU8s LRZWVUWm+88wGlAeFjQnVeasM1NBRW2bkMkPjUCxEk93S95BeyBK3o7UsNdsrhgtnKVU ykexTEW1V95SqWAhpKw3QCL+xLTMvY54AYGy8GOwfMDoljdCb9ebAiK+FEi8dudZej9K SkQj3xNoOQLOP+llb6POAjraikm3LE7+9vySjfw4OYcSk34g1QgsIv0JFHHi6BnDYjC7 q8I0aTPPnoIR8hmpjnWejZdupqx9TveBwRWWgjK8tTwzsp/gvF+16H66TVmuq9niJjGJ Oy0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=16w7KIxIKq7DVWU2jRPaeALdZ2xcgpzjcsj3qPwpVus=; b=JTnxz1bxoK14RatPu0XPBevou7hTa7pzXPqSIF6PgKL8CgTNlpqFv7pfGRdnsxEZK5 CaUAVF1mPASTWxfEHkXCZ9sZdG7M+993jbfiWglg1YnNtQvQQjRsTpSVfdB6AFQQoBFm vviEpyfLkIEHfVweFVgnADaMtKYK8yymIo+QmeqmuUVMjFP1l0ca7wW8A9YZWAjD1bKx xsvOFfIkZfEl5CxwYlLcH+e5csgr+aWNmiTvgeDxIp6i0OaWnWIc4qAU61NqNgxSI8oJ pf6Qug7nGTZrIYw064EmUjbmIqYC2q33iEnX4sklQQHktWRY1gM1slZHhHQUB8/lEEp0 gW5g== X-Gm-Message-State: AOUpUlEKrtlJ/eXMk7wv+Ym3LRFxUseyt3OfmldyKqBr+0A1POY9h6qW 0Uw9Q9Nf3B9yMK/YYHdFLgId/g== X-Google-Smtp-Source: AAOMgpeDLN3wf5IeEkZNAzQxRDoFvqbyq1IlL3cCULB9Bm6J8j0uDTc+1FjzIftvLJ3+G9QtTrn7+Q== X-Received: by 2002:a17:902:7683:: with SMTP id m3-v6mr22545198pll.255.1532563169664; Wed, 25 Jul 2018 16:59:29 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:29 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 2/9] proc/kcore: don't grab lock for memory hotplug notifier Date: Wed, 25 Jul 2018 16:59:13 -0700 Message-Id: <93fa8dc895f40f2b85d706779b3cd2902567ff7a.1532563124.git.osandov@fb.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval The memory hotplug notifier kcore_callback() only needs kclist_lock to prevent races with __kcore_update_ram(), but we can easily eliminate that race by using an atomic xchg() in __kcore_update_ram(). This is preparation for converting kclist_lock to an rwsem. Reviewed-by: Andrew Morton Signed-off-by: Omar Sandoval --- fs/proc/kcore.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index b0b9a76f28d6..e83f15a4f66d 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -118,7 +118,7 @@ static void __kcore_update_ram(struct list_head *list) LIST_HEAD(garbage); write_lock(&kclist_lock); - if (kcore_need_update) { + if (xchg(&kcore_need_update, 0)) { list_for_each_entry_safe(pos, tmp, &kclist_head, list) { if (pos->type == KCORE_RAM || pos->type == KCORE_VMEMMAP) @@ -127,7 +127,6 @@ static void __kcore_update_ram(struct list_head *list) list_splice_tail(list, &kclist_head); } else list_splice(list, &garbage); - kcore_need_update = 0; proc_root_kcore->size = get_kcore_size(&nphdr, &size); write_unlock(&kclist_lock); @@ -593,9 +592,8 @@ static int __meminit kcore_callback(struct notifier_block *self, switch (action) { case MEM_ONLINE: case MEM_OFFLINE: - write_lock(&kclist_lock); kcore_need_update = 1; - write_unlock(&kclist_lock); + break; } return NOTIFY_OK; } From patchwork Wed Jul 25 23:59:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544953 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1BC4D139A for ; Thu, 26 Jul 2018 00:00:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A83A2A9D4 for ; Thu, 26 Jul 2018 00:00:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F321D2A9D9; Thu, 26 Jul 2018 00:00:15 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93AD32A9D4 for ; Thu, 26 Jul 2018 00:00:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728559AbeGZBNg (ORCPT ); Wed, 25 Jul 2018 21:13:36 -0400 Received: from mail-pl0-f65.google.com ([209.85.160.65]:36739 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728481AbeGZBNf (ORCPT ); Wed, 25 Jul 2018 21:13:35 -0400 Received: by mail-pl0-f65.google.com with SMTP id e11-v6so3951454plb.3 for ; Wed, 25 Jul 2018 16:59:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OyWywDrz0yNlctIEZKfvqcYdJMHey6G7QhHf0bJ4Juc=; b=N+/iL5fejFKJBgL86c7dIvORG0UbpLxXfzFOWXP3pvNMvfaVPbBxgHlYEEmatjRxO1 ZYrCA2mIfw5RdzrG0/2x3YVOR4i1s1UHv00LhZnUi9F721HAX1LxuXt8dYBkJsTPsTHZ +JN56l4lqbeLrh84/Afh5C6UWkVeM1Xguq7P8fAoG+EiN7iTL5IxxGNTBK7LHpEwOuyY 1cjCJHXKf7TJuxbr2FYjlRyYdDnsP1aunU6wcvZlymHIlJcFP7snq6/v12Ayl6g9Wcvs j7YjLhVzOK+I5/jyrA5PgtZPbycR2a9pKnKB+X6A6lFFifJfXKC7TJV1KKwcYLGraZz7 vWcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OyWywDrz0yNlctIEZKfvqcYdJMHey6G7QhHf0bJ4Juc=; b=ofvzu/8HHqgplm/mr3TDlid28d3nPzJsbeuumgsAtZSHKNJ8QkSvyuYRV3HSw8s/Mo OAIt4ewXPYaSu2SeJDD5U48H2g6jBmT2IfIZ+idgThACs5dDR1bZpjBERofWAKJcTeuA giGRXi82/ITzBFt9qifkoDEh7YbF+W5K3XhC3k7Lg6XbEnc8u2J0z61C7xc/vzk+kZqr xgROFy6Gr+K4rMbwQZwiUOwlM6p7yUPjmWBCD8CKMfop1J6dhHsYkOv4EWj8LQpI86ij 9gCA5v34SDmydg9ru0plHCqzL57hwe0lYMBF91Fty1o3WWWPhW68cgsHBrhMhGNipZF/ piKQ== X-Gm-Message-State: AOUpUlF9bPdXzzjFie/gGw/PprNza5f8l0rHZL36Z7jWiWs/GasDG/Pw /3/yZvrHw0DaeGE2ou+mNEFVpA== X-Google-Smtp-Source: AAOMgpdIe/Dzyo7suaCjIk7sSJ1zT4w7ASuNcgmrQ0/ilyLri8disTx0IhCoYtKuTnqRDdVHjmJImQ== X-Received: by 2002:a17:902:9695:: with SMTP id n21-v6mr23026395plp.6.1532563170918; Wed, 25 Jul 2018 16:59:30 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:30 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 3/9] proc/kcore: replace kclist_lock rwlock with rwsem Date: Wed, 25 Jul 2018 16:59:14 -0700 Message-Id: <51ba5cba7c43ec5ddce8023054c99943fad02b6d.1532563124.git.osandov@fb.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval Now we only need kclist_lock from user context and at fs init time, and the following changes need to sleep while holding the kclist_lock. Signed-off-by: Omar Sandoval --- fs/proc/kcore.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index e83f15a4f66d..ae43a97d511d 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -59,7 +59,7 @@ struct memelfnote }; static LIST_HEAD(kclist_head); -static DEFINE_RWLOCK(kclist_lock); +static DECLARE_RWSEM(kclist_lock); static int kcore_need_update = 1; /* This doesn't grab kclist_lock, so it should only be used at init time. */ @@ -117,7 +117,7 @@ static void __kcore_update_ram(struct list_head *list) struct kcore_list *tmp, *pos; LIST_HEAD(garbage); - write_lock(&kclist_lock); + down_write(&kclist_lock); if (xchg(&kcore_need_update, 0)) { list_for_each_entry_safe(pos, tmp, &kclist_head, list) { if (pos->type == KCORE_RAM @@ -128,7 +128,7 @@ static void __kcore_update_ram(struct list_head *list) } else list_splice(list, &garbage); proc_root_kcore->size = get_kcore_size(&nphdr, &size); - write_unlock(&kclist_lock); + up_write(&kclist_lock); free_kclist_ents(&garbage); } @@ -451,11 +451,11 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) int nphdr; unsigned long start; - read_lock(&kclist_lock); + down_read(&kclist_lock); size = get_kcore_size(&nphdr, &elf_buflen); if (buflen == 0 || *fpos >= size) { - read_unlock(&kclist_lock); + up_read(&kclist_lock); return 0; } @@ -472,11 +472,11 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) tsz = buflen; elf_buf = kzalloc(elf_buflen, GFP_ATOMIC); if (!elf_buf) { - read_unlock(&kclist_lock); + up_read(&kclist_lock); return -ENOMEM; } elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen); - read_unlock(&kclist_lock); + up_read(&kclist_lock); if (copy_to_user(buffer, elf_buf + *fpos, tsz)) { kfree(elf_buf); return -EFAULT; @@ -491,7 +491,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) if (buflen == 0) return acc; } else - read_unlock(&kclist_lock); + up_read(&kclist_lock); /* * Check to see if our file offset matches with any of @@ -504,12 +504,12 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) while (buflen) { struct kcore_list *m; - read_lock(&kclist_lock); + down_read(&kclist_lock); list_for_each_entry(m, &kclist_head, list) { if (start >= m->addr && start < (m->addr+m->size)) break; } - read_unlock(&kclist_lock); + up_read(&kclist_lock); if (&m->list == &kclist_head) { if (clear_user(buffer, tsz)) From patchwork Wed Jul 25 23:59:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544941 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CBB9A1822 for ; Wed, 25 Jul 2018 23:59:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA69A2A9AC for ; Wed, 25 Jul 2018 23:59:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AECF22A9CE; Wed, 25 Jul 2018 23:59:35 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3021B2A9AC for ; Wed, 25 Jul 2018 23:59:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728587AbeGZBNh (ORCPT ); Wed, 25 Jul 2018 21:13:37 -0400 Received: from mail-pl0-f68.google.com ([209.85.160.68]:39538 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728486AbeGZBNg (ORCPT ); Wed, 25 Jul 2018 21:13:36 -0400 Received: by mail-pl0-f68.google.com with SMTP id m1-v6so3945878plt.6 for ; Wed, 25 Jul 2018 16:59:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jejP2yrNUB7zHbhkc1Ji+iKVjXdsuDSSW0aNb0+t3w4=; b=rSaiZYTBpJvtTfER7UyiV0vgtVPMHJvNbL0d4NHd5473ZGsxdd+dYdRIj67JFVkkyg Sjbsmzvmn0TZEhSBKGKWDMpD25h0vS4uhjn9vuNu0g1Ivv1z4VvRQXP5Z4dU99R58TPV ZOIpm+jukziTkScJrGF++3tdsbgIK5Bq8JVjHIsQLmTPdS9BadKWIS/l/+p3ZmCE80Aa X4KoF1xmDIzZJ+OgfWj584/TShSJ4BsUcsxl7fUHSofEUIiBgoBR7KGEWarIom7Hr/9j fNJsVR6QWMXu0r+vLWgkNGFoq8GWm2IuFsF4sX+d7vRLq8vX6r6eA2tYtP3p5do3ieCZ cznQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jejP2yrNUB7zHbhkc1Ji+iKVjXdsuDSSW0aNb0+t3w4=; b=nh2k5p8gCfKCE2vn567FdyDAOdLs+rvO6DfleOQP4tVyeGA4qvAkd9ZhSQbon5LiI7 ewb+uQH2Vc4xm5Q6yUmDPvd+uDY73wGeiSDb/doMidUWkVi4oNDfMMtL1QTJvtt8Fw2o 4lIQmE6NUuM81dTw8IAND5u/biR2pcDBvg/qoHEY5Y+z0FKOusc3w1ueoUiQLaykfv1R RJanUcMwEGkcMxKhx/S01INEXiycXEWklRAGv+HysG96ozh+uuQGPHai0kotLH+eyXOf esPQZ0yC6bmD4htZJjHhNpRLZZFrHsAMOwiUMM5zw/z+8l1XgqdddqCagqLSV/Tj8GdD isBw== X-Gm-Message-State: AOUpUlGgWwV47Vg+BSKEKkfdgteAsNlsulxq7m0fBu2s4ox5CbhZMKqI RJLWmd82rXxeJ5Z0FOg73HycJw== X-Google-Smtp-Source: AAOMgpccLSWJN9v6HHbhkX6ZmvWKOSmfWL2cGtcOoKvSutpphfb9usi+bvhnJGyT0Q+u60aS+Ty/NA== X-Received: by 2002:a17:902:ab90:: with SMTP id f16-v6mr23534126plr.182.1532563172107; Wed, 25 Jul 2018 16:59:32 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:31 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 4/9] proc/kcore: fix memory hotplug vs multiple opens race Date: Wed, 25 Jul 2018 16:59:15 -0700 Message-Id: <0eed0c15cf94c6869fcefccae46759d702d7118f.1532563124.git.osandov@fb.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval There's a theoretical race condition that will cause /proc/kcore to miss a memory hotplug event: CPU0 CPU1 // hotplug event 1 kcore_need_update = 1 open_kcore() open_kcore() kcore_update_ram() kcore_update_ram() // Walk RAM // Walk RAM __kcore_update_ram() __kcore_update_ram() kcore_need_update = 0 // hotplug event 2 kcore_need_update = 1 kcore_need_update = 0 Note that CPU1 set up the RAM kcore entries with the state after hotplug event 1 but cleared the flag for hotplug event 2. The RAM entries will therefore be stale until there is another hotplug event. This is an extremely unlikely sequence of events, but the fix makes the synchronization saner, anyways: we serialize the entire update sequence, which means that whoever clears the flag will always succeed in replacing the kcore list. Signed-off-by: Omar Sandoval --- fs/proc/kcore.c | 93 +++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 49 deletions(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index ae43a97d511d..95aa988c5b5d 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -98,53 +98,15 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) return size + *elf_buflen; } -static void free_kclist_ents(struct list_head *head) -{ - struct kcore_list *tmp, *pos; - - list_for_each_entry_safe(pos, tmp, head, list) { - list_del(&pos->list); - kfree(pos); - } -} -/* - * Replace all KCORE_RAM/KCORE_VMEMMAP information with passed list. - */ -static void __kcore_update_ram(struct list_head *list) -{ - int nphdr; - size_t size; - struct kcore_list *tmp, *pos; - LIST_HEAD(garbage); - - down_write(&kclist_lock); - if (xchg(&kcore_need_update, 0)) { - list_for_each_entry_safe(pos, tmp, &kclist_head, list) { - if (pos->type == KCORE_RAM - || pos->type == KCORE_VMEMMAP) - list_move(&pos->list, &garbage); - } - list_splice_tail(list, &kclist_head); - } else - list_splice(list, &garbage); - proc_root_kcore->size = get_kcore_size(&nphdr, &size); - up_write(&kclist_lock); - - free_kclist_ents(&garbage); -} - - #ifdef CONFIG_HIGHMEM /* * If no highmem, we can assume [0...max_low_pfn) continuous range of memory * because memory hole is not as big as !HIGHMEM case. * (HIGHMEM is special because part of memory is _invisible_ from the kernel.) */ -static int kcore_update_ram(void) +static int kcore_ram_list(struct list_head *head) { - LIST_HEAD(head); struct kcore_list *ent; - int ret = 0; ent = kmalloc(sizeof(*ent), GFP_KERNEL); if (!ent) @@ -152,9 +114,8 @@ static int kcore_update_ram(void) ent->addr = (unsigned long)__va(0); ent->size = max_low_pfn << PAGE_SHIFT; ent->type = KCORE_RAM; - list_add(&ent->list, &head); - __kcore_update_ram(&head); - return ret; + list_add(&ent->list, head); + return 0; } #else /* !CONFIG_HIGHMEM */ @@ -253,11 +214,10 @@ kclist_add_private(unsigned long pfn, unsigned long nr_pages, void *arg) return 1; } -static int kcore_update_ram(void) +static int kcore_ram_list(struct list_head *list) { int nid, ret; unsigned long end_pfn; - LIST_HEAD(head); /* Not inialized....update now */ /* find out "max pfn" */ @@ -269,15 +229,50 @@ static int kcore_update_ram(void) end_pfn = node_end; } /* scan 0 to max_pfn */ - ret = walk_system_ram_range(0, end_pfn, &head, kclist_add_private); - if (ret) { - free_kclist_ents(&head); + ret = walk_system_ram_range(0, end_pfn, list, kclist_add_private); + if (ret) return -ENOMEM; + return 0; +} +#endif /* CONFIG_HIGHMEM */ + +static int kcore_update_ram(void) +{ + LIST_HEAD(list); + LIST_HEAD(garbage); + int nphdr; + size_t size; + struct kcore_list *tmp, *pos; + int ret = 0; + + down_write(&kclist_lock); + if (!xchg(&kcore_need_update, 0)) + goto out; + + ret = kcore_ram_list(&list); + if (ret) { + /* Couldn't get the RAM list, try again next time. */ + WRITE_ONCE(kcore_need_update, 1); + list_splice_tail(&list, &garbage); + goto out; + } + + list_for_each_entry_safe(pos, tmp, &kclist_head, list) { + if (pos->type == KCORE_RAM || pos->type == KCORE_VMEMMAP) + list_move(&pos->list, &garbage); + } + list_splice_tail(&list, &kclist_head); + + proc_root_kcore->size = get_kcore_size(&nphdr, &size); + +out: + up_write(&kclist_lock); + list_for_each_entry_safe(pos, tmp, &garbage, list) { + list_del(&pos->list); + kfree(pos); } - __kcore_update_ram(&head); return ret; } -#endif /* CONFIG_HIGHMEM */ /*****************************************************************************/ /* From patchwork Wed Jul 25 23:59:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544951 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CACD9139A for ; Thu, 26 Jul 2018 00:00:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9C762A9D4 for ; Thu, 26 Jul 2018 00:00:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AD5472A9D9; Thu, 26 Jul 2018 00:00:12 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3737F2A9D4 for ; Thu, 26 Jul 2018 00:00:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728756AbeGZBOK (ORCPT ); Wed, 25 Jul 2018 21:14:10 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:42324 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727852AbeGZBNi (ORCPT ); Wed, 25 Jul 2018 21:13:38 -0400 Received: by mail-pg1-f194.google.com with SMTP id y4-v6so6308014pgp.9 for ; Wed, 25 Jul 2018 16:59:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oqP8n13yd1O4w8D2hrqTvkNxTGtNRWoLTcWbgV3cEAM=; b=ly9JcTajj7UB9jQWSaJE6M+IG6z8jZbvYHKMUovAl6kAjBlAj29xS6UBeWrYv99vTf DmroyeAJpx31HCOOPJsEPnrk/G24nwvh4v9RtN4/eQGIyxl50kbPO89W5bEbuNYhjtEa hY/DVVWc2O8j2rc+Z/aP3phWgrKve0UATmihj5YYoRUWh4URcdWEhlzXggOKDxg0UFXf TVHxPURJpsOS299oweYDnAM+SQ2chkV2dd3Yjh9O9fPI547hS9ogde2LZ1UwiJ44HEQg FLtp4ZrH7xYyMvMp9/9eSbhadMhB7k8IwTmUp2ITwxxYrUK6YwSK/+TwDn6Vqdj/MoeV bSlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oqP8n13yd1O4w8D2hrqTvkNxTGtNRWoLTcWbgV3cEAM=; b=h/YXlhCjUEcHPpeaXj610GgBunNwniZqdTG2vn6FeBITlwEaZ7Q4HTuI8sKtNwH3Jv Q+vZ52wpbdSxYpoLU8ysNHaGScpu97LxTL4vzvz3oQOS1DI764ip9uawElG09H6+3tTV rotcq1BL5/3KoMCCvTafVet7xgAsi90o/Vyd98rXX9uJHeV30jufi4lJXX3Eq5HjS6Ze cYFPz6jBcSV+WAXzHMyOgw6f4+q/A5Rv23n/dB2wW2YRDR1j5ovlppkwm70ewBuwc7Gg C/IlZYD52RBeh7IPXIiU7EYrl1RLsOzD1JOnl6wc7i2spdGIn+4SnOKqrSZa1PnxWTn3 7CsQ== X-Gm-Message-State: AOUpUlHUZTnAExWyKtYfzanU9SpW0CrMLCA5hS3cxOR9m/IaGkp4Kpv1 aRjAFeB9wtyyi06vDukfCJb0+g== X-Google-Smtp-Source: AAOMgpcl/Pz6JS8SJDNPc4gi4YOKowmiwd1ciXjAtzWaBXKXil4E8XV68VUMLBwF+6rmug0eE+6BRg== X-Received: by 2002:a62:843:: with SMTP id c64-v6mr24267445pfd.14.1532563173339; Wed, 25 Jul 2018 16:59:33 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:32 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 5/9] proc/kcore: hold lock during read Date: Wed, 25 Jul 2018 16:59:16 -0700 Message-Id: X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval Now that we're using an rwsem, we can hold it during the entirety of read_kcore() and have a common return path. This is preparation for the next change. Signed-off-by: Omar Sandoval --- fs/proc/kcore.c | 70 ++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 95aa988c5b5d..dc34642bbdb7 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -440,19 +440,18 @@ static ssize_t read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) { char *buf = file->private_data; - ssize_t acc = 0; size_t size, tsz; size_t elf_buflen; int nphdr; unsigned long start; + size_t orig_buflen = buflen; + int ret = 0; down_read(&kclist_lock); size = get_kcore_size(&nphdr, &elf_buflen); - if (buflen == 0 || *fpos >= size) { - up_read(&kclist_lock); - return 0; - } + if (buflen == 0 || *fpos >= size) + goto out; /* trim buflen to not go beyond EOF */ if (buflen > size - *fpos) @@ -465,28 +464,26 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) tsz = elf_buflen - *fpos; if (buflen < tsz) tsz = buflen; - elf_buf = kzalloc(elf_buflen, GFP_ATOMIC); + elf_buf = kzalloc(elf_buflen, GFP_KERNEL); if (!elf_buf) { - up_read(&kclist_lock); - return -ENOMEM; + ret = -ENOMEM; + goto out; } elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen); - up_read(&kclist_lock); if (copy_to_user(buffer, elf_buf + *fpos, tsz)) { kfree(elf_buf); - return -EFAULT; + ret = -EFAULT; + goto out; } kfree(elf_buf); buflen -= tsz; *fpos += tsz; buffer += tsz; - acc += tsz; /* leave now if filled buffer already */ if (buflen == 0) - return acc; - } else - up_read(&kclist_lock); + goto out; + } /* * Check to see if our file offset matches with any of @@ -499,25 +496,29 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) while (buflen) { struct kcore_list *m; - down_read(&kclist_lock); list_for_each_entry(m, &kclist_head, list) { if (start >= m->addr && start < (m->addr+m->size)) break; } - up_read(&kclist_lock); if (&m->list == &kclist_head) { - if (clear_user(buffer, tsz)) - return -EFAULT; + if (clear_user(buffer, tsz)) { + ret = -EFAULT; + goto out; + } } else if (m->type == KCORE_VMALLOC) { vread(buf, (char *)start, tsz); /* we have to zero-fill user buffer even if no read */ - if (copy_to_user(buffer, buf, tsz)) - return -EFAULT; + if (copy_to_user(buffer, buf, tsz)) { + ret = -EFAULT; + goto out; + } } else if (m->type == KCORE_USER) { /* User page is handled prior to normal kernel page: */ - if (copy_to_user(buffer, (char *)start, tsz)) - return -EFAULT; + if (copy_to_user(buffer, (char *)start, tsz)) { + ret = -EFAULT; + goto out; + } } else { if (kern_addr_valid(start)) { /* @@ -525,26 +526,35 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) * hardened user copy kernel text checks. */ if (probe_kernel_read(buf, (void *) start, tsz)) { - if (clear_user(buffer, tsz)) - return -EFAULT; + if (clear_user(buffer, tsz)) { + ret = -EFAULT; + goto out; + } } else { - if (copy_to_user(buffer, buf, tsz)) - return -EFAULT; + if (copy_to_user(buffer, buf, tsz)) { + ret = -EFAULT; + goto out; + } } } else { - if (clear_user(buffer, tsz)) - return -EFAULT; + if (clear_user(buffer, tsz)) { + ret = -EFAULT; + goto out; + } } } buflen -= tsz; *fpos += tsz; buffer += tsz; - acc += tsz; start += tsz; tsz = (buflen > PAGE_SIZE ? PAGE_SIZE : buflen); } - return acc; +out: + up_read(&kclist_lock); + if (ret) + return ret; + return orig_buflen - buflen; } From patchwork Wed Jul 25 23:59:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544947 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 623671822 for ; Wed, 25 Jul 2018 23:59:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 508C82A9C4 for ; Wed, 25 Jul 2018 23:59:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 44DD02A9D4; Wed, 25 Jul 2018 23:59:58 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 530092A9C4 for ; Wed, 25 Jul 2018 23:59:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728649AbeGZBNl (ORCPT ); Wed, 25 Jul 2018 21:13:41 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:37925 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728579AbeGZBNj (ORCPT ); Wed, 25 Jul 2018 21:13:39 -0400 Received: by mail-pg1-f194.google.com with SMTP id k3-v6so6310080pgq.5 for ; Wed, 25 Jul 2018 16:59:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7Fn7b5BcXHji/BjrZDgAToax3z3FLWmW1Mh6h9L8PD8=; b=2OfgrUeznMrsC3nZLE4vW7u5YYh5mmNxAs4W1nYpOPB5DUHXTaCPbarq0tzRQ6pdjo 1ZOtQ83s5zFXZA0eB3RmMuIXylHDUlbmYzkEPBLsudPDRVTMA1c5oxink+2EhRs43yaD BRw2DS0rHYQoKTzbNYR3dnHmBlBMPV3laKdp40PWB/9v+2PPrEUciRcQ7utddfuhojHq SLpFVtOCooB22Bbob2fdD47LpaECWgt4pV37KvE1XPsSsHaUgonRW98pH23R8e13je/Y /NUre+JMUCIzuJBfqpPKtqP+YuOr9DEZVtIh9z1x+IXroVcRw2vESkbf7brgihKQyTwF /MQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7Fn7b5BcXHji/BjrZDgAToax3z3FLWmW1Mh6h9L8PD8=; b=PP1yCoITWgFAq/sHsZefS9N0dg7AAQyimZG6agC1obypz33DOBfUNrSBjicv4QbOKL /rdediKYL78nPwewk9DcPEue8bvIT/gcq9/RfhGz1mVoomf37N01aizFJ/hzMGJsmfxG 5Dc1wza2HVb/fuylJmCib+/Xg6s+6nyHqx+ZOFUNCBZ1V074sCO4gFGwZV2KqvzllaDa +y5opB/r+y3cYzWHiW9pdltKlMHoqo+/BiPx+Swmb+tCeXARY/LX8mrx/Dez7H6IOtQp HbqfxgLyyKRZv3zrEC08Yo0vpPKipcRrPuedyqeExHKTPqicv8sTEVp3qbr9VwKtu/yj LpUQ== X-Gm-Message-State: AOUpUlHpK66KRHAfklFeiNYOoGCQg+TpMwrEfCJJhBKSv8EEmCEeeiTQ meElGxi8iYVBabNpT+z8kfV+zw== X-Google-Smtp-Source: AAOMgpeNSUjIB270/O0/LQLK576zZFlDXb//ddkAy7elqDP+JlJPs17ycpj40ZTnBPBc9LhXNh4tdg== X-Received: by 2002:a63:9741:: with SMTP id d1-v6mr21770519pgo.403.1532563174589; Wed, 25 Jul 2018 16:59:34 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:34 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 6/9] proc/kcore: clean up ELF header generation Date: Wed, 25 Jul 2018 16:59:17 -0700 Message-Id: <9877fbf510da820bd7f9a5907fa64463bae5e59a.1532563124.git.osandov@fb.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval Currently, the ELF file header, program headers, and note segment are allocated all at once, in some icky code dating back to 2.3. Programs tend to read the file header, then the program headers, then the note segment, all separately, so this is a waste of effort. It's cleaner and more efficient to handle the three separately. Signed-off-by: Omar Sandoval --- fs/proc/kcore.c | 350 +++++++++++++++++++----------------------------- 1 file changed, 141 insertions(+), 209 deletions(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index dc34642bbdb7..808ef9afd084 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -49,15 +49,6 @@ static struct proc_dir_entry *proc_root_kcore; #define kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET) #endif -/* An ELF note in memory */ -struct memelfnote -{ - const char *name; - int type; - unsigned int datasz; - void *data; -}; - static LIST_HEAD(kclist_head); static DECLARE_RWSEM(kclist_lock); static int kcore_need_update = 1; @@ -73,7 +64,8 @@ void __init kclist_add(struct kcore_list *new, void *addr, size_t size, list_add_tail(&new->list, &kclist_head); } -static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) +static size_t get_kcore_size(int *nphdr, size_t *phdrs_len, size_t *notes_len, + size_t *data_offset) { size_t try, size; struct kcore_list *m; @@ -87,15 +79,15 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) size = try; *nphdr = *nphdr + 1; } - *elf_buflen = sizeof(struct elfhdr) + - (*nphdr + 2)*sizeof(struct elf_phdr) + - 3 * ((sizeof(struct elf_note)) + - roundup(sizeof(CORE_STR), 4)) + - roundup(sizeof(struct elf_prstatus), 4) + - roundup(sizeof(struct elf_prpsinfo), 4) + - roundup(arch_task_struct_size, 4); - *elf_buflen = PAGE_ALIGN(*elf_buflen); - return size + *elf_buflen; + + *phdrs_len = *nphdr * sizeof(struct elf_phdr); + *notes_len = (3 * (sizeof(struct elf_note) + ALIGN(sizeof(CORE_STR), 4)) + + ALIGN(sizeof(struct elf_prstatus), 4) + + ALIGN(sizeof(struct elf_prpsinfo), 4) + + ALIGN(arch_task_struct_size, 4)); + *data_offset = PAGE_ALIGN(sizeof(struct elfhdr) + *phdrs_len + + *notes_len); + return *data_offset + size; } #ifdef CONFIG_HIGHMEM @@ -241,7 +233,7 @@ static int kcore_update_ram(void) LIST_HEAD(list); LIST_HEAD(garbage); int nphdr; - size_t size; + size_t phdrs_len, notes_len, data_offset; struct kcore_list *tmp, *pos; int ret = 0; @@ -263,7 +255,8 @@ static int kcore_update_ram(void) } list_splice_tail(&list, &kclist_head); - proc_root_kcore->size = get_kcore_size(&nphdr, &size); + proc_root_kcore->size = get_kcore_size(&nphdr, &phdrs_len, ¬es_len, + &data_offset); out: up_write(&kclist_lock); @@ -274,228 +267,168 @@ static int kcore_update_ram(void) return ret; } -/*****************************************************************************/ -/* - * determine size of ELF note - */ -static int notesize(struct memelfnote *en) +static void append_kcore_note(char *notes, size_t *i, const char *name, + unsigned int type, const void *desc, + size_t descsz) { - int sz; - - sz = sizeof(struct elf_note); - sz += roundup((strlen(en->name) + 1), 4); - sz += roundup(en->datasz, 4); - - return sz; -} /* end notesize() */ - -/*****************************************************************************/ -/* - * store a note in the header buffer - */ -static char *storenote(struct memelfnote *men, char *bufp) -{ - struct elf_note en; - -#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0) - - en.n_namesz = strlen(men->name) + 1; - en.n_descsz = men->datasz; - en.n_type = men->type; - - DUMP_WRITE(&en, sizeof(en)); - DUMP_WRITE(men->name, en.n_namesz); - - /* XXX - cast from long long to long to avoid need for libgcc.a */ - bufp = (char*) roundup((unsigned long)bufp,4); - DUMP_WRITE(men->data, men->datasz); - bufp = (char*) roundup((unsigned long)bufp,4); - -#undef DUMP_WRITE - - return bufp; -} /* end storenote() */ - -/* - * store an ELF coredump header in the supplied buffer - * nphdr is the number of elf_phdr to insert - */ -static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) -{ - struct elf_prstatus prstatus; /* NT_PRSTATUS */ - struct elf_prpsinfo prpsinfo; /* NT_PRPSINFO */ - struct elf_phdr *nhdr, *phdr; - struct elfhdr *elf; - struct memelfnote notes[3]; - off_t offset = 0; - struct kcore_list *m; - - /* setup ELF header */ - elf = (struct elfhdr *) bufp; - bufp += sizeof(struct elfhdr); - offset += sizeof(struct elfhdr); - memcpy(elf->e_ident, ELFMAG, SELFMAG); - elf->e_ident[EI_CLASS] = ELF_CLASS; - elf->e_ident[EI_DATA] = ELF_DATA; - elf->e_ident[EI_VERSION]= EV_CURRENT; - elf->e_ident[EI_OSABI] = ELF_OSABI; - memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); - elf->e_type = ET_CORE; - elf->e_machine = ELF_ARCH; - elf->e_version = EV_CURRENT; - elf->e_entry = 0; - elf->e_phoff = sizeof(struct elfhdr); - elf->e_shoff = 0; - elf->e_flags = ELF_CORE_EFLAGS; - elf->e_ehsize = sizeof(struct elfhdr); - elf->e_phentsize= sizeof(struct elf_phdr); - elf->e_phnum = nphdr; - elf->e_shentsize= 0; - elf->e_shnum = 0; - elf->e_shstrndx = 0; - - /* setup ELF PT_NOTE program header */ - nhdr = (struct elf_phdr *) bufp; - bufp += sizeof(struct elf_phdr); - offset += sizeof(struct elf_phdr); - nhdr->p_type = PT_NOTE; - nhdr->p_offset = 0; - nhdr->p_vaddr = 0; - nhdr->p_paddr = 0; - nhdr->p_filesz = 0; - nhdr->p_memsz = 0; - nhdr->p_flags = 0; - nhdr->p_align = 0; - - /* setup ELF PT_LOAD program header for every area */ - list_for_each_entry(m, &kclist_head, list) { - phdr = (struct elf_phdr *) bufp; - bufp += sizeof(struct elf_phdr); - offset += sizeof(struct elf_phdr); - - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_offset = kc_vaddr_to_offset(m->addr) + dataoff; - phdr->p_vaddr = (size_t)m->addr; - if (m->type == KCORE_RAM) - phdr->p_paddr = __pa(m->addr); - else if (m->type == KCORE_TEXT) - phdr->p_paddr = __pa_symbol(m->addr); - else - phdr->p_paddr = (elf_addr_t)-1; - phdr->p_filesz = phdr->p_memsz = m->size; - phdr->p_align = PAGE_SIZE; - } - - /* - * Set up the notes in similar form to SVR4 core dumps made - * with info from their /proc. - */ - nhdr->p_offset = offset; - - /* set up the process status */ - notes[0].name = CORE_STR; - notes[0].type = NT_PRSTATUS; - notes[0].datasz = sizeof(struct elf_prstatus); - notes[0].data = &prstatus; - - memset(&prstatus, 0, sizeof(struct elf_prstatus)); - - nhdr->p_filesz = notesize(¬es[0]); - bufp = storenote(¬es[0], bufp); - - /* set up the process info */ - notes[1].name = CORE_STR; - notes[1].type = NT_PRPSINFO; - notes[1].datasz = sizeof(struct elf_prpsinfo); - notes[1].data = &prpsinfo; - - memset(&prpsinfo, 0, sizeof(struct elf_prpsinfo)); - prpsinfo.pr_state = 0; - prpsinfo.pr_sname = 'R'; - prpsinfo.pr_zomb = 0; - - strcpy(prpsinfo.pr_fname, "vmlinux"); - strlcpy(prpsinfo.pr_psargs, saved_command_line, sizeof(prpsinfo.pr_psargs)); - - nhdr->p_filesz += notesize(¬es[1]); - bufp = storenote(¬es[1], bufp); - - /* set up the task structure */ - notes[2].name = CORE_STR; - notes[2].type = NT_TASKSTRUCT; - notes[2].datasz = arch_task_struct_size; - notes[2].data = current; - - nhdr->p_filesz += notesize(¬es[2]); - bufp = storenote(¬es[2], bufp); - -} /* end elf_kcore_store_hdr() */ + struct elf_note *note = (struct elf_note *)¬es[*i]; + + note->n_namesz = strlen(name) + 1; + note->n_descsz = descsz; + note->n_type = type; + *i += sizeof(*note); + memcpy(¬es[*i], name, note->n_namesz); + *i = ALIGN(*i + note->n_namesz, 4); + memcpy(¬es[*i], desc, descsz); + *i = ALIGN(*i + descsz, 4); +} -/*****************************************************************************/ -/* - * read from the ELF header and then kernel memory - */ static ssize_t read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) { char *buf = file->private_data; - size_t size, tsz; - size_t elf_buflen; + size_t phdrs_offset, notes_offset, data_offset; + size_t phdrs_len, notes_len; + struct kcore_list *m; + size_t tsz; int nphdr; unsigned long start; size_t orig_buflen = buflen; int ret = 0; down_read(&kclist_lock); - size = get_kcore_size(&nphdr, &elf_buflen); - if (buflen == 0 || *fpos >= size) - goto out; + get_kcore_size(&nphdr, &phdrs_len, ¬es_len, &data_offset); + phdrs_offset = sizeof(struct elfhdr); + notes_offset = phdrs_offset + phdrs_len; + + /* ELF file header. */ + if (buflen && *fpos < sizeof(struct elfhdr)) { + struct elfhdr ehdr = { + .e_ident = { + [EI_MAG0] = ELFMAG0, + [EI_MAG1] = ELFMAG1, + [EI_MAG2] = ELFMAG2, + [EI_MAG3] = ELFMAG3, + [EI_CLASS] = ELF_CLASS, + [EI_DATA] = ELF_DATA, + [EI_VERSION] = EV_CURRENT, + [EI_OSABI] = ELF_OSABI, + }, + .e_type = ET_CORE, + .e_machine = ELF_ARCH, + .e_version = EV_CURRENT, + .e_phoff = sizeof(struct elfhdr), + .e_flags = ELF_CORE_EFLAGS, + .e_ehsize = sizeof(struct elfhdr), + .e_phentsize = sizeof(struct elf_phdr), + .e_phnum = nphdr, + }; + + tsz = min_t(size_t, buflen, sizeof(struct elfhdr) - *fpos); + if (copy_to_user(buffer, (char *)&ehdr + *fpos, tsz)) { + ret = -EFAULT; + goto out; + } - /* trim buflen to not go beyond EOF */ - if (buflen > size - *fpos) - buflen = size - *fpos; + buffer += tsz; + buflen -= tsz; + *fpos += tsz; + } - /* construct an ELF core header if we'll need some of it */ - if (*fpos < elf_buflen) { - char * elf_buf; + /* ELF program headers. */ + if (buflen && *fpos < phdrs_offset + phdrs_len) { + struct elf_phdr *phdrs, *phdr; - tsz = elf_buflen - *fpos; - if (buflen < tsz) - tsz = buflen; - elf_buf = kzalloc(elf_buflen, GFP_KERNEL); - if (!elf_buf) { + phdrs = kzalloc(phdrs_len, GFP_KERNEL); + if (!phdrs) { ret = -ENOMEM; goto out; } - elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen); - if (copy_to_user(buffer, elf_buf + *fpos, tsz)) { - kfree(elf_buf); + + phdrs[0].p_type = PT_NOTE; + phdrs[0].p_offset = notes_offset; + phdrs[0].p_filesz = notes_len; + + phdr = &phdrs[1]; + list_for_each_entry(m, &kclist_head, list) { + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R | PF_W | PF_X; + phdr->p_offset = kc_vaddr_to_offset(m->addr) + data_offset; + phdr->p_vaddr = (size_t)m->addr; + if (m->type == KCORE_RAM) + phdr->p_paddr = __pa(m->addr); + else if (m->type == KCORE_TEXT) + phdr->p_paddr = __pa_symbol(m->addr); + else + phdr->p_paddr = (elf_addr_t)-1; + phdr->p_filesz = phdr->p_memsz = m->size; + phdr->p_align = PAGE_SIZE; + phdr++; + } + + tsz = min_t(size_t, buflen, phdrs_offset + phdrs_len - *fpos); + if (copy_to_user(buffer, (char *)phdrs + *fpos - phdrs_offset, + tsz)) { + kfree(phdrs); ret = -EFAULT; goto out; } - kfree(elf_buf); + kfree(phdrs); + + buffer += tsz; buflen -= tsz; *fpos += tsz; - buffer += tsz; + } + + /* ELF note segment. */ + if (buflen && *fpos < notes_offset + notes_len) { + struct elf_prstatus prstatus = {}; + struct elf_prpsinfo prpsinfo = { + .pr_sname = 'R', + .pr_fname = "vmlinux", + }; + char *notes; + size_t i = 0; + + strlcpy(prpsinfo.pr_psargs, saved_command_line, + sizeof(prpsinfo.pr_psargs)); + + notes = kzalloc(notes_len, GFP_KERNEL); + if (!notes) { + ret = -ENOMEM; + goto out; + } + + append_kcore_note(notes, &i, CORE_STR, NT_PRSTATUS, &prstatus, + sizeof(prstatus)); + append_kcore_note(notes, &i, CORE_STR, NT_PRPSINFO, &prpsinfo, + sizeof(prpsinfo)); + append_kcore_note(notes, &i, CORE_STR, NT_TASKSTRUCT, current, + arch_task_struct_size); - /* leave now if filled buffer already */ - if (buflen == 0) + tsz = min_t(size_t, buflen, notes_offset + notes_len - *fpos); + if (copy_to_user(buffer, notes + *fpos - notes_offset, tsz)) { + kfree(notes); + ret = -EFAULT; goto out; + } + kfree(notes); + + buffer += tsz; + buflen -= tsz; + *fpos += tsz; } /* * Check to see if our file offset matches with any of * the addresses in the elf_phdr on our list. */ - start = kc_offset_to_vaddr(*fpos - elf_buflen); + start = kc_offset_to_vaddr(*fpos - data_offset); if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) tsz = buflen; - - while (buflen) { - struct kcore_list *m; + while (buflen) { list_for_each_entry(m, &kclist_head, list) { if (start >= m->addr && start < (m->addr+m->size)) break; @@ -557,7 +490,6 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) return orig_buflen - buflen; } - static int open_kcore(struct inode *inode, struct file *filp) { if (!capable(CAP_SYS_RAWIO)) From patchwork Wed Jul 25 23:59:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544949 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EB4E1112E for ; Thu, 26 Jul 2018 00:00:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA0E72A9D4 for ; Thu, 26 Jul 2018 00:00:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CDB4A2A9E7; Thu, 26 Jul 2018 00:00:03 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C194F2A9D5 for ; Thu, 26 Jul 2018 00:00:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728628AbeGZBNl (ORCPT ); Wed, 25 Jul 2018 21:13:41 -0400 Received: from mail-pg1-f193.google.com ([209.85.215.193]:42326 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728617AbeGZBNk (ORCPT ); Wed, 25 Jul 2018 21:13:40 -0400 Received: by mail-pg1-f193.google.com with SMTP id y4-v6so6308061pgp.9 for ; Wed, 25 Jul 2018 16:59:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eIz2LDT3jNvOV+6SjD3rQhz1JXwGXwb08hD64XrvRP4=; b=ln0eyIrIZj6RZhlG4r7vuHKAJ58xktXZ6ANYV+nvwes2yRxDFoGPIii+k26dgf3KW5 pT5IF1ayFzjqRrnI0CUjdYYTxSLSNrH8i2AvvpF1J9duD4OQfU5NB1Qe8pOgGpEstxca ZInMRUls8SwZ7UQzGZ7aEtPHasBNXgLborqYaq3xcA4dTSULDSbsa8sAOBrRTsfgJofY FUmJadfe6M60tSHxmUi77W3nFblA5PrtcWkfvuMNrt/zk0iXPYmEDNN3h3JkqHR66+4G jYvdtvEeDTaYjfJiLUzd/VRoamjkb3jxbbh3O8Tu/Mo5JCBoWhmqRTqe/2x6xVwoWCIg j4UQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eIz2LDT3jNvOV+6SjD3rQhz1JXwGXwb08hD64XrvRP4=; b=RaVNjF2++hvREwrScfbkjJ/13e5Nt/M5Ov7AVNs1tj8mekRqgWc6Ig9NfiGbvIOTwl YpVpLJ+sde4KUEoir0643spY4DKoI1v4e/nE/MUwmtGNdWSAXxQQ8/HvEoPARfK3c1mh +fhNhATqDVrIOz47v49ye9eja6ZA8wA2FV70a8hImGwaBDxVhA60sqcTuWUgpqrMgnuN A0fcwmZW5/UXbIj5S4RGu4qvbNBb7TJU8iZoPnza3tqcGhmLcEWdwEd2j2Bb7dAcHn7j F70gXjz6qIRJGcxph63GuFewvc7rClvyCZ2guY9HatNBEX906Uwb53R6ZWwfagoAGdbD wuYg== X-Gm-Message-State: AOUpUlFgcxStmK2dvg1A8dSgl8l0EkLYPOwtiIRNkU85tgiEqpj7/ofX 4imCB2g6dB5mXMvA0kGRxpZAlg== X-Google-Smtp-Source: AAOMgpeJxn5s+2QROoPSSiqA06mQjcWeQYJBh0Hw08ByAaG2Bj8RP0CxFbmvdVx6pR3NOy/k03sY8Q== X-Received: by 2002:aa7:850b:: with SMTP id v11-v6mr23846859pfn.165.1532563175628; Wed, 25 Jul 2018 16:59:35 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:35 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 7/9] proc/kcore: optimize multiple page reads Date: Wed, 25 Jul 2018 16:59:18 -0700 Message-Id: X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval The current code does a full search of the segment list every time for every page. This is wasteful, since it's almost certain that the next page will be in the same segment. Instead, check if the previous segment covers the current page before doing the list search. Signed-off-by: Omar Sandoval --- fs/proc/kcore.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 808ef9afd084..758c14e46a44 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -428,10 +428,18 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen) tsz = buflen; + m = NULL; while (buflen) { - list_for_each_entry(m, &kclist_head, list) { - if (start >= m->addr && start < (m->addr+m->size)) - break; + /* + * If this is the first iteration or the address is not within + * the previous entry, search for a matching entry. + */ + if (!m || start < m->addr || start >= m->addr + m->size) { + list_for_each_entry(m, &kclist_head, list) { + if (start >= m->addr && + start < m->addr + m->size) + break; + } } if (&m->list == &kclist_head) { From patchwork Wed Jul 25 23:59:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544945 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 401EB139A for ; Wed, 25 Jul 2018 23:59:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2F6022A9C4 for ; Wed, 25 Jul 2018 23:59:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 23CBE2A9D4; Wed, 25 Jul 2018 23:59:57 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C26952A9C4 for ; Wed, 25 Jul 2018 23:59:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728745AbeGZBN7 (ORCPT ); Wed, 25 Jul 2018 21:13:59 -0400 Received: from mail-pf1-f193.google.com ([209.85.210.193]:36650 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728619AbeGZBNl (ORCPT ); Wed, 25 Jul 2018 21:13:41 -0400 Received: by mail-pf1-f193.google.com with SMTP id d14-v6so2200495pfo.3 for ; Wed, 25 Jul 2018 16:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hIvpKGKNqRxV3JggszEiPqiqS8x7Has4uKzatQ8KMas=; b=VgwH9ehGKsvLCpNCJBZ3LT/BPS3kwPfYyYKCdvQLTjgI2AWqFcsKmr1fkMCFT/BbGJ S85GvHFFcSzPQU1l4YKlJHpcQQ6zcChxOOFcnSLBdTSbPFOu+7ixg2949tYvLMmtAbT6 2QGcFpKlnIoPWeoNKDmXnDDeV9cbZhwWm3nzfzTXZEf47Lg5/GueHAjRZMS8Mb0s6KjY +JZYhVbDDVeG9TLa7leCTOOcozVaPDpVoDi1yB+IgzN6vhJwflPRtnuL5BdgKpU2KzI3 fgKdrprTyv4+bS0dD/o9uBqWURDlqMIN9XC4N2OwkVBsdoy7yKlnbK4z7xkf4crXj6qa NK/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hIvpKGKNqRxV3JggszEiPqiqS8x7Has4uKzatQ8KMas=; b=sXcs6+WRexySlx97cz4U4cuTUZ0s5mp6g7wK8jGgOCdJASNZZAfRC1ljjaLm0i0vWS r/ufqFU4iDubxNj8juLhW2oa/tUOnrmnxP5E1bitzEsBdihEoFDCGI+t5Js8D66gr6fY r43JAWFIilxOOZyb3i9dkNu4ypuRLyOG3mI7X0gImVGkvtIhQX6CAyiRcjICekbcA2f8 8pCP0y9EbPMuXlaQAAH1gYXda68PyEi0XbdrHQMV72szMR2V9FDSQq/HJ9R1EmpLAGC8 EhLdMROrEzZUnDe1W1PovX3RlNWseGeGCvkeH81tT9QVOj43CP321FjBymgigkPqkGdS oVtg== X-Gm-Message-State: AOUpUlHC7mm0kuI78DQsDOxdnaXpqK9TobwCynN8o0PnX0ykN/G4xgvu rTbE0b7LBXglof0qfgxQfvondg== X-Google-Smtp-Source: AAOMgpdZj07WntgfPeGIVoOtHqMpHSMjPYh78SgKm6VEPVadyXrVGLL9NS5jXIHQ0H+CV4VWdQypBw== X-Received: by 2002:a63:5055:: with SMTP id q21-v6mr21675081pgl.397.1532563176737; Wed, 25 Jul 2018 16:59:36 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:36 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 8/9] crash_core: use VMCOREINFO_SYMBOL_ARRAY() for swapper_pg_dir Date: Wed, 25 Jul 2018 16:59:19 -0700 Message-Id: X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval This is preparation for allowing CRASH_CORE to be enabled for any architecture. swapper_pg_dir is always either an array or a macro expanding to NULL. In the latter case, VMCOREINFO_SYMBOL() won't work, as it tries to take the address of the given symbol: #define VMCOREINFO_SYMBOL(name) \ vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name) Instead, use VMCOREINFO_SYMBOL_ARRAY(), which uses the value: #define VMCOREINFO_SYMBOL_ARRAY(name) \ vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name) This is the same thing for the array case but isn't an error for the macro case. Signed-off-by: Omar Sandoval --- kernel/crash_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/crash_core.c b/kernel/crash_core.c index b66aced5e8c2..e7b4025c7b24 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -401,7 +401,7 @@ static int __init crash_save_vmcoreinfo_init(void) VMCOREINFO_SYMBOL(init_uts_ns); VMCOREINFO_SYMBOL(node_online_map); #ifdef CONFIG_MMU - VMCOREINFO_SYMBOL(swapper_pg_dir); + VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir); #endif VMCOREINFO_SYMBOL(_stext); VMCOREINFO_SYMBOL(vmap_area_list); From patchwork Wed Jul 25 23:59:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 10544943 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4CCD9139A for ; Wed, 25 Jul 2018 23:59:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C1112A9C4 for ; Wed, 25 Jul 2018 23:59:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3044F2A9D4; Wed, 25 Jul 2018 23:59:52 +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=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A26C62A9C4 for ; Wed, 25 Jul 2018 23:59:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728744AbeGZBNx (ORCPT ); Wed, 25 Jul 2018 21:13:53 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:40432 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728618AbeGZBNm (ORCPT ); Wed, 25 Jul 2018 21:13:42 -0400 Received: by mail-pf1-f196.google.com with SMTP id e13-v6so2198929pff.7 for ; Wed, 25 Jul 2018 16:59:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DoMV7TytVt090kzod3DGVHCSv6oSSVhrF14RLi5zS0Q=; b=P1sFx1vYYkdRIyMcY55Bpnb8HMNJbzetxAaR2/WZKLYWP8zUgBAYpknQJjCy6U3UmG zfBPSnj+b00gUNwZCj8jblaxSQJnVYtzwvnGFGGCUFhZugPD3nBYHrq3FWvMjZU+d2T/ y9lgD5ZwxKxJhiV7Aa+eqpW33hQUlQudAnbl3MrdyZZrygje1nnKdWlU6gV4XbZsbZZp +FeSUribSeZR1xuVVDBsZcjzo5uGYiJrSGnViB/lPoaCPfkZy7YbomYUlomYPIe6yPU6 JPi49nff3u3tLmjbRGdTcVICL+cNu8JhJLKl1mPIaRpFoPARjU/dNj9qChCud2GnQIcB 1cZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DoMV7TytVt090kzod3DGVHCSv6oSSVhrF14RLi5zS0Q=; b=o6ugl71NAfnnx9TJXyJgVjEU/jD06qXb7bT+jS1LyTyODll4z/HURHluRj6cMRQ29W QDSetO/UO9M62VVNyucZpXuBfgVij1orK490Srf0NpSy+cWJfov7mCl0EJLT5jN6DDNQ RAkt106iSd49A/vguiq899WdyNkwXdK9WFZ/ZgssJpbnXFKq46MwcPmVpR4iNDfosTwy RKmcHsWCvHHW9C7NrAWu/UeM1MdFUSYf/c4JKj0/2Dy/bT80IQFxCevIq0G+yNBRMgKF oN8q10Z8DZhmNBhHeKSOIfu1Fe/zA40EQYK1k2LiBMS3nRkr28fbMFhRMAcAhktvmbDi BtTQ== X-Gm-Message-State: AOUpUlEqqEo75ppWxfsht9mpLgiIJJM/7E+ejYsgsGt5aiLsOKEUAP/R XTYbYGXkhG06RvxhVqPtipLzNQ== X-Google-Smtp-Source: AAOMgpfqieXQ3k61Cm6pNbhqli4zjNhTk0lz9CFxEOhw8G7HXU7zAV1gg64GhvzMPuX+G7LIiyvv4g== X-Received: by 2002:a63:524e:: with SMTP id s14-v6mr22814746pgl.35.1532563177747; Wed, 25 Jul 2018 16:59:37 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:180::1:8d38]) by smtp.gmail.com with ESMTPSA id 65-v6sm23188753pfq.81.2018.07.25.16.59.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Jul 2018 16:59:37 -0700 (PDT) From: Omar Sandoval To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, Andrew Morton Cc: Alexey Dobriyan , Eric Biederman , James Morse , Bhupesh Sharma , kernel-team@fb.com Subject: [PATCH v4 9/9] proc/kcore: add vmcoreinfo note to /proc/kcore Date: Wed, 25 Jul 2018 16:59:20 -0700 Message-Id: X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval The vmcoreinfo information is useful for runtime debugging tools, not just for crash dumps. A lot of this information can be determined by other means, but this is much more convenient, and it only adds a page at most to the file. Signed-off-by: Omar Sandoval --- fs/proc/Kconfig | 1 + fs/proc/kcore.c | 18 ++++++++++++++++-- include/linux/crash_core.h | 2 ++ kernel/crash_core.c | 4 ++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig index 0eaeb41453f5..817c02b13b1d 100644 --- a/fs/proc/Kconfig +++ b/fs/proc/Kconfig @@ -31,6 +31,7 @@ config PROC_FS config PROC_KCORE bool "/proc/kcore support" if !ARM depends on PROC_FS && MMU + select CRASH_CORE help Provides a virtual ELF core file of the live kernel. This can be read with gdb and other ELF tools. No modifications can be diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 758c14e46a44..80464432dfe6 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -10,6 +10,7 @@ * Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar */ +#include #include #include #include @@ -81,10 +82,13 @@ static size_t get_kcore_size(int *nphdr, size_t *phdrs_len, size_t *notes_len, } *phdrs_len = *nphdr * sizeof(struct elf_phdr); - *notes_len = (3 * (sizeof(struct elf_note) + ALIGN(sizeof(CORE_STR), 4)) + + *notes_len = (4 * sizeof(struct elf_note) + + 3 * ALIGN(sizeof(CORE_STR), 4) + + VMCOREINFO_NOTE_NAME_BYTES + ALIGN(sizeof(struct elf_prstatus), 4) + ALIGN(sizeof(struct elf_prpsinfo), 4) + - ALIGN(arch_task_struct_size, 4)); + ALIGN(arch_task_struct_size, 4) + + ALIGN(vmcoreinfo_size, 4)); *data_offset = PAGE_ALIGN(sizeof(struct elfhdr) + *phdrs_len + *notes_len); return *data_offset + size; @@ -406,6 +410,16 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) sizeof(prpsinfo)); append_kcore_note(notes, &i, CORE_STR, NT_TASKSTRUCT, current, arch_task_struct_size); + /* + * vmcoreinfo_size is mostly constant after init time, but it + * can be changed by crash_save_vmcoreinfo(). Racing here with a + * panic on another CPU before the machine goes down is insanely + * unlikely, but it's better to not leave potential buffer + * overflows lying around, regardless. + */ + append_kcore_note(notes, &i, VMCOREINFO_NOTE_NAME, 0, + vmcoreinfo_data, + min(vmcoreinfo_size, notes_len - i)); tsz = min_t(size_t, buflen, notes_offset + notes_len - *fpos); if (copy_to_user(buffer, notes + *fpos - notes_offset, tsz)) { diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index b511f6d24b42..525510a9f965 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -60,6 +60,8 @@ phys_addr_t paddr_vmcoreinfo_note(void); #define VMCOREINFO_CONFIG(name) \ vmcoreinfo_append_str("CONFIG_%s=y\n", #name) +extern unsigned char *vmcoreinfo_data; +extern size_t vmcoreinfo_size; extern u32 *vmcoreinfo_note; Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type, diff --git a/kernel/crash_core.c b/kernel/crash_core.c index e7b4025c7b24..a683bfb0530f 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -14,8 +14,8 @@ #include /* vmcoreinfo stuff */ -static unsigned char *vmcoreinfo_data; -static size_t vmcoreinfo_size; +unsigned char *vmcoreinfo_data; +size_t vmcoreinfo_size; u32 *vmcoreinfo_note; /* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */