Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp7649959pxb; Thu, 18 Feb 2021 16:27:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJzTBtZWRsDP7vsWvGF7QOVs8h65qVp9AHfDN9xgTsPtg5jDO1RM8fuJkit5Tl+TUW4XeAEM X-Received: by 2002:a17:906:5905:: with SMTP id h5mr4798842ejq.531.1613694437819; Thu, 18 Feb 2021 16:27:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613694437; cv=none; d=google.com; s=arc-20160816; b=ngEXegJH1t8CS8U8HOTEqbWDIoY7rQlRyc6LKy/TArIMxbCI07BsatuhNFbE6tFV/T njaWuQoudSrXmuaqivcTRwlO08Om3++4CaW2h1XrcQjb8dVY88+KMdeN1pkxNSWUfvPV F4BA2CNO6mqwIiL0o8nRH5V75TS99SJ+C2gQBKp+przg1f3VxW/c9Ts3VdAdnzNy9zn9 VcA3ZKUwet2jVX7n+JRSmljHJd5aPVcaYMHfZcsmcrhsHEULJklO4Ali+KJPBfIrjNP0 rwZKtI/5LJSCNeZZtZ9D+F40VAFJ8Lj+InNqlZDxIwz5UQ5pv36Wx0PLSzaL4hiVWZHm E+Tg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:sender:dkim-signature; bh=hrKEbBMgsE8JTGg8XVXnIk1GaeWuGUQgi5pPA+IiEQ4=; b=aS+V2JElfNTQvpFZcSncYk9Z4xmIs0/IvKxj7+lkqQEue/qboHzy9APoAWwpbcEeba Na2elA8lXwepYnFGntThGdy4ZeQUUhaVlIJOUvwEiwoZ/s58UeLzr/1+/y4/l8/m3xNp C3qRbl/MnxNoajLrbMXsJm98A5kRh/29EsTu7iM2i7jCAriN0+e9+k3WL7JAoP1vrseY uxCQwnMU+rcG9SFzWczSj53TiKOHtb1PLKOVB9XHtFjzEUNy0wagSeStB+MapnhIUUEI n9ZCfZv39/bOISTSheqEcBM1dNSbDInu7303Uq3o9cCI6TImH9xnkxqs+SjJmcQ/MqOQ KSPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=ak7Lim4r; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y11si5593795edj.305.2021.02.18.16.26.54; Thu, 18 Feb 2021 16:27:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=ak7Lim4r; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229876AbhBSAXS (ORCPT + 99 others); Thu, 18 Feb 2021 19:23:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229826AbhBSAXO (ORCPT ); Thu, 18 Feb 2021 19:23:14 -0500 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3050FC061756 for ; Thu, 18 Feb 2021 16:22:34 -0800 (PST) Received: by mail-qt1-x84a.google.com with SMTP id p20so2247570qtn.23 for ; Thu, 18 Feb 2021 16:22:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=hrKEbBMgsE8JTGg8XVXnIk1GaeWuGUQgi5pPA+IiEQ4=; b=ak7Lim4r6UGdoX3Z1PzU0EoMlkFZ/AwbBJ5Xeb7WEfkr3zrhXbt30Zi0mxiTLr1gM3 oOJsBHdsz3YfynCuuPUwXxPVzGpQsbNeL10ozod7WcGa112DcPa9aYLmwJqLAYf+23aN 1xOTtE1TMka7NPRtgbayLjP6VxKPa+JTnee8iqw0eH4kyTV1qOEYf/ZF/gICBeh4RiFv 8aCTOJMmkkZSZ2DOYbIGhlXMUqZZ2kCZi+CutvvE8liFmyynXXxxhPhSdP9MmkV+xM2v 2VssB8mFg+9TgHPgUmX4078E4QPksWkhXQJnJfj+fr2HMge/AdaAn31PTd+odLG3IxQP qNxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=hrKEbBMgsE8JTGg8XVXnIk1GaeWuGUQgi5pPA+IiEQ4=; b=jNn1cdfQx+gDW8Yg8wZZO5XqmXaRbt9fvhBsG+j8dja5u3JjXQW+DBh8l/PZgllqZf VHAivV9QsYyLkMyTFwKkM7Jrbh4qIf9zk+eCNmbXPlBP+ZO+H6kvCTe0ukjKihTqv8rn 7ftg4GD34RGvgo0hCtOhMcdq7Vp1KZFmh0rEpOdapd6EA/TmCXfMA5d7yQlJE3ghkWTq LEPRbEhTY+aGL2blUoM/grJgSUupNivuZzirWd1idMG+w0YZ/fIVmqdnN9Jgg8Dc9JBw XN/m+QSN5g8lf65LVMsDgxvdo9YLKNY/lPEADho56Ky6+LDUmJjukRJcNsVm/CPi4lbi B2WA== X-Gm-Message-State: AOAM532E60xS73f9iV0DRHH+MD+kS0HRqJoaXMs5c/MoUAHG5YHZctIU SwXkYHTdp6zSZP+IxBiwtx9fp39kNkHDs63Q Sender: "andreyknvl via sendgmr" X-Received: from andreyknvl3.muc.corp.google.com ([2a00:79e0:15:13:2d89:512e:587f:6e72]) (user=andreyknvl job=sendgmr) by 2002:a0c:9e13:: with SMTP id p19mr7008653qve.12.1613694153272; Thu, 18 Feb 2021 16:22:33 -0800 (PST) Date: Fri, 19 Feb 2021 01:22:24 +0100 In-Reply-To: Message-Id: Mime-Version: 1.0 References: X-Mailer: git-send-email 2.30.0.617.g56c4b15f3c-goog Subject: [PATCH v2 2/2] mm, kasan: don't poison boot memory with tag-based modes From: Andrey Konovalov To: Andrew Morton Cc: Catalin Marinas , Will Deacon , Vincenzo Frascino , Dmitry Vyukov , Andrey Ryabinin , Alexander Potapenko , Marco Elver , Peter Collingbourne , Evgenii Stepanov , Branislav Rankov , Kevin Brodsky , Christoph Hellwig , kasan-dev@googlegroups.com, linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrey Konovalov Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org During boot, all non-reserved memblock memory is exposed to page_alloc via memblock_free_pages->__free_pages_core(). This results in kasan_free_pages() being called, which poisons that memory. Poisoning all that memory lengthens boot time. The most noticeable effect is observed with the HW_TAGS mode. A boot-time impact may potentially also affect systems with large amount of RAM. This patch changes the tag-based modes to not poison the memory during the memblock->page_alloc transition. An exception is made for KASAN_GENERIC. Since it marks all new memory as accessible, not poisoning the memory released from memblock will lead to KASAN missing invalid boot-time accesses to that memory. With KASAN_SW_TAGS, as it uses the invalid 0xFE tag as the default tag for all memory, it won't miss bad boot-time accesses even if the poisoning of memblock memory is removed. With KASAN_HW_TAGS, the default memory tags values are unspecified. Therefore, if memblock poisoning is removed, this KASAN mode will miss the mentioned type of boot-time bugs with a 1/16 probability. This is taken as an acceptable trafe-off. Internally, the poisoning is removed as follows. __free_pages_core() is used when exposing fresh memory during system boot and when onlining memory during hotplug. This patch adds a new FPI_SKIP_KASAN_POISON flag and passes it to __free_pages_ok() through free_pages_prepare() from __free_pages_core(). If FPI_SKIP_KASAN_POISON is set, kasan_free_pages() is not called. All memory allocated normally when the boot is over keeps getting poisoned as usual. Reviewed-by: Catalin Marinas Signed-off-by: Andrey Konovalov --- Changes v1->v2: - Only drop memblock poisoning for tag-based KASAN modes. --- mm/page_alloc.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 0b55c9c95364..c89e7b107514 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -108,6 +108,17 @@ typedef int __bitwise fpi_t; */ #define FPI_TO_TAIL ((__force fpi_t)BIT(1)) +/* + * Don't poison memory with KASAN (only for the tag-based modes). + * During boot, all non-reserved memblock memory is exposed to page_alloc. + * Poisoning all that memory lengthens boot time, especially on systems with + * large amount of RAM. This flag is used to skip that poisoning. + * This is only done for the tag-based KASAN modes, as those are able to + * detect memory corruptions with the memory tags assigned by default. + * All memory allocated normally after boot gets poisoned as usual. + */ +#define FPI_SKIP_KASAN_POISON ((__force fpi_t)BIT(2)) + /* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */ static DEFINE_MUTEX(pcp_batch_high_lock); #define MIN_PERCPU_PAGELIST_FRACTION (8) @@ -384,10 +395,15 @@ static DEFINE_STATIC_KEY_TRUE(deferred_pages); * on-demand allocation and then freed again before the deferred pages * initialization is done, but this is not likely to happen. */ -static inline void kasan_free_nondeferred_pages(struct page *page, int order) +static inline void kasan_free_nondeferred_pages(struct page *page, int order, + fpi_t fpi_flags) { - if (!static_branch_unlikely(&deferred_pages)) - kasan_free_pages(page, order); + if (static_branch_unlikely(&deferred_pages)) + return; + if (!IS_ENABLED(CONFIG_KASAN_GENERIC) && + (fpi_flags & FPI_SKIP_KASAN_POISON)) + return; + kasan_free_pages(page, order); } /* Returns true if the struct page for the pfn is uninitialised */ @@ -438,7 +454,14 @@ defer_init(int nid, unsigned long pfn, unsigned long end_pfn) return false; } #else -#define kasan_free_nondeferred_pages(p, o) kasan_free_pages(p, o) +static inline void kasan_free_nondeferred_pages(struct page *page, int order, + fpi_t fpi_flags) +{ + if (!IS_ENABLED(CONFIG_KASAN_GENERIC) && + (fpi_flags & FPI_SKIP_KASAN_POISON)) + return; + kasan_free_pages(page, order); +} static inline bool early_page_uninitialised(unsigned long pfn) { @@ -1216,7 +1239,7 @@ static void kernel_init_free_pages(struct page *page, int numpages) } static __always_inline bool free_pages_prepare(struct page *page, - unsigned int order, bool check_free) + unsigned int order, bool check_free, fpi_t fpi_flags) { int bad = 0; @@ -1290,7 +1313,7 @@ static __always_inline bool free_pages_prepare(struct page *page, debug_pagealloc_unmap_pages(page, 1 << order); - kasan_free_nondeferred_pages(page, order); + kasan_free_nondeferred_pages(page, order, fpi_flags); return true; } @@ -1303,7 +1326,7 @@ static __always_inline bool free_pages_prepare(struct page *page, */ static bool free_pcp_prepare(struct page *page) { - return free_pages_prepare(page, 0, true); + return free_pages_prepare(page, 0, true, FPI_NONE); } static bool bulkfree_pcp_prepare(struct page *page) @@ -1323,9 +1346,9 @@ static bool bulkfree_pcp_prepare(struct page *page) static bool free_pcp_prepare(struct page *page) { if (debug_pagealloc_enabled_static()) - return free_pages_prepare(page, 0, true); + return free_pages_prepare(page, 0, true, FPI_NONE); else - return free_pages_prepare(page, 0, false); + return free_pages_prepare(page, 0, false, FPI_NONE); } static bool bulkfree_pcp_prepare(struct page *page) @@ -1533,7 +1556,7 @@ static void __free_pages_ok(struct page *page, unsigned int order, int migratetype; unsigned long pfn = page_to_pfn(page); - if (!free_pages_prepare(page, order, true)) + if (!free_pages_prepare(page, order, true, fpi_flags)) return; migratetype = get_pfnblock_migratetype(page, pfn); @@ -1570,7 +1593,7 @@ void __free_pages_core(struct page *page, unsigned int order) * Bypass PCP and place fresh pages right to the tail, primarily * relevant for memory onlining. */ - __free_pages_ok(page, order, FPI_TO_TAIL); + __free_pages_ok(page, order, FPI_TO_TAIL | FPI_SKIP_KASAN_POISON); } #ifdef CONFIG_NEED_MULTIPLE_NODES -- 2.30.0.617.g56c4b15f3c-goog