Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp2727756pxb; Mon, 25 Apr 2022 00:39:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJznFXztZpQSSelNIUn7rP/P1xb7sEECVhOZE7KYtzUTx4dY9ObNlRhOwbTArz8yyo6L/ZDf X-Received: by 2002:a17:907:1c8f:b0:6e8:f898:63bb with SMTP id nb15-20020a1709071c8f00b006e8f89863bbmr15734686ejc.721.1650872347182; Mon, 25 Apr 2022 00:39:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650872347; cv=none; d=google.com; s=arc-20160816; b=ZbfwT6izxJSJGMgNryUKq0T/YaCUXaQSjIfsbtBWD5kcjHRrOtTS4xIFAGEbU96ima 3+/VR6xBFH0SEfR1K1e9Cy9W8YjwjablcaXMgHoUDHiA643BYjRbLgE7S0E0rrHkJYJ8 p6BjORFI+L36OPIP0MwfCO9SBY2L4Jpx5MTxQz2cxwJfv+nZDpPJcZr99bjpKirzOsTk 3hbC9g74k4XtqrVkGCJU4iAEnZqkpt75Q7qw9PBhFQhtXHmH0EkJhT9orYPHvNibHDYy PcSUpNzdYOqYcem/WzEH1tDNzFvLJ5BqAF0/yzTDKqHumCNpv08dK4+BRNJI7ngrqbzu PpOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=yRwmwKwYb4KZeIA5jOGkkBwCFjLH0EDfu0DNN4WypE0=; b=si5GVqYUkNYq7KEeKSn1w5eFTO94BOltQWAyypkIcL8D80KxhZuCcdMH0yMdYaEPuA bRMYQK05bbyqXfSL/gNBg/7NAghq4Besq1ZGwbp9bA5xK3THDiihhOV5LLuuLVw+icWe RGKXzCsKIkx48PMgbEb8oq3hnxui9sEiR1Yo7z8GZnzWwDHNYs+cESmdbtYtqc/lYpN3 J4uvVpbGKwp3WEwgJo28UQyVFcpCkEtPAB+enXgq9ZNcd+EBwEF5ePs2BNlXpUsiI79y q3Hwwoc4r0mXq/d3vWtkaj2IdvBkXGRkr69KHNqs6Gante61SnrgwnBrazeNJMtpo9Xz nX3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Vn3m9tCw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m5-20020a509985000000b00423e4d00368si12037940edb.176.2022.04.25.00.38.43; Mon, 25 Apr 2022 00:39:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Vn3m9tCw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239629AbiDXVWY (ORCPT + 99 others); Sun, 24 Apr 2022 17:22:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233662AbiDXVWU (ORCPT ); Sun, 24 Apr 2022 17:22:20 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B849C7E97; Sun, 24 Apr 2022 14:19:18 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3407B6134A; Sun, 24 Apr 2022 21:19:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8B622C385AF; Sun, 24 Apr 2022 21:19:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1650835157; bh=rpvLJ5VKob5Uj1ZAM+7DRly1YYYXvxcS7/lthEv2kog=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Vn3m9tCwgrCz93GMBKTN6oEwtTM0p0cufoPU3Q45IXCdPkQMJ9VxlYrehAExZPqmZ H4zu4/oaPdeMjUigYRQ2P6z89J2WkMZ6Pwr9BmXubnQZ5Ozmj6AAbGRBbWcUWcKrzK myU0daw6faLz+f7zdovWoPQBAwfLQFm5jnSDfsvkZ5jfd7G0HAaOa8P/ci7TIStFO2 M/D1ZLaI//h/4+1HBSvII5V9qTWcw3xRFTCqd+mFTPDCzj0NkV7ZlNlyZfYj6YmHFL Z2CXBhFKSwSmQJ6DLh5ttI00RyuCMQsBfCQNUw6mi+Xxbbl3f4RvPnuABr2b5lRYTv mIbYb9+WFv9rw== Received: by mail-ot1-f44.google.com with SMTP id r14-20020a9d750e000000b00605446d683eso9540289otk.10; Sun, 24 Apr 2022 14:19:17 -0700 (PDT) X-Gm-Message-State: AOAM532JBi/C796ZW20wW24HQ81fRRZ/8APE3vPvVlQIoouBeX6YyQ6R WV7c9P6lyfknGbawRk9MuvQqQ00PhOETuLJwXDs= X-Received: by 2002:a05:6830:242d:b0:605:589f:e2a7 with SMTP id k13-20020a056830242d00b00605589fe2a7mr5403190ots.71.1650835156633; Sun, 24 Apr 2022 14:19:16 -0700 (PDT) MIME-Version: 1.0 References: <20220424172044.22220-1-rppt@kernel.org> In-Reply-To: <20220424172044.22220-1-rppt@kernel.org> From: Ard Biesheuvel Date: Sun, 24 Apr 2022 23:19:05 +0200 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH] arm[64]/memremap: don't abuse pfn_valid() to ensure presence of linear map To: Mike Rapoport Cc: Linux Kernel Mailing List , Andrew Morton , Catalin Marinas , Greg Kroah-Hartman , Guillaume Tucker , Mark Brown , Mark-PK Tsai , Mike Rapoport , Russell King , Tony Lindgren , Will Deacon , "kernelci . org bot" , kernelci-results@groups.io, Linux ARM , "# 3.4.x" Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, 24 Apr 2022 at 19:22, Mike Rapoport wrote: > > From: Mike Rapoport > > The semantics of pfn_valid() is to check presence of the memory map for a > PFN and not whether a PFN is covered by the linear map. The memory map may > be present for NOMAP memory regions, but they won't be mapped in the linear > mapping. Accessing such regions via __va() when they are memremap()'ed > will cause a crash. > > On v5.4.y the crash happens on qemu-arm with UEFI [1]: > > <1>[ 0.084476] 8<--- cut here --- > <1>[ 0.084595] Unable to handle kernel paging request at virtual address dfb76000 > <1>[ 0.084938] pgd = (ptrval) > <1>[ 0.085038] [dfb76000] *pgd=5f7fe801, *pte=00000000, *ppte=00000000 > > ... > > <4>[ 0.093923] [] (memcpy) from [] (dmi_setup+0x60/0x418) > <4>[ 0.094204] [] (dmi_setup) from [] (arm_dmi_init+0x8/0x10) > <4>[ 0.094408] [] (arm_dmi_init) from [] (do_one_initcall+0x50/0x228) > <4>[ 0.094619] [] (do_one_initcall) from [] (kernel_init_freeable+0x15c/0x1f8) > <4>[ 0.094841] [] (kernel_init_freeable) from [] (kernel_init+0x8/0x10c) > <4>[ 0.095057] [] (kernel_init) from [] (ret_from_fork+0x14/0x2c) > > On kernels v5.10.y and newer the same crash won't reproduce on ARM because > commit b10d6bca8720 ("arch, drivers: replace for_each_membock() with > for_each_mem_range()") changed the way memory regions are registered in the > resource tree, but that merely covers up the problem. > > On ARM64 memory resources registered in yet another way and there the > issue of wrong usage of pfn_valid() to ensure availability of the linear > map is also covered. > > Implement arch_memremap_can_ram_remap() on ARM and ARM64 to prevent access > to NOMAP regions via the linear mapping in memremap(). > > Link: https://lore.kernel.org/all/Yl65zxGgFzF1Okac@sirena.org.uk > Reported-by: "kernelci.org bot" > Tested-by: Mark Brown > Cc: stable@vger.kernel.org # 5.4+ > Signed-off-by: Mike Rapoport > --- > arch/arm/include/asm/io.h | 4 ++++ > arch/arm/mm/ioremap.c | 9 ++++++++- > arch/arm64/include/asm/io.h | 4 ++++ > arch/arm64/mm/ioremap.c | 8 ++++++++ > kernel/iomem.c | 2 +- > 5 files changed, 25 insertions(+), 2 deletions(-) > > diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h > index 0c70eb688a00..fbb2eeea7285 100644 > --- a/arch/arm/include/asm/io.h > +++ b/arch/arm/include/asm/io.h > @@ -145,6 +145,10 @@ extern void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t, > unsigned int, void *); > extern void (*arch_iounmap)(volatile void __iomem *); > > +extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, > + unsigned long flags); > +#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap > + > /* > * Bad read/write accesses... > */ > diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c > index aa08bcb72db9..6eb1ad24544d 100644 > --- a/arch/arm/mm/ioremap.c > +++ b/arch/arm/mm/ioremap.c > @@ -43,7 +43,6 @@ > #include > #include "mm.h" > > - > LIST_HEAD(static_vmlist); > > static struct static_vm *find_static_vm_paddr(phys_addr_t paddr, > @@ -493,3 +492,11 @@ void __init early_ioremap_init(void) > { > early_ioremap_setup(); > } > + > +bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, > + unsigned long flags) > +{ > + unsigned long pfn = PHYS_PFN(offset); > + > + return memblock_is_map_memory(pfn); > +} > diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h > index 7fd836bea7eb..3995652daf81 100644 > --- a/arch/arm64/include/asm/io.h > +++ b/arch/arm64/include/asm/io.h > @@ -192,4 +192,8 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size); > extern int valid_phys_addr_range(phys_addr_t addr, size_t size); > extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); > > +extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, > + unsigned long flags); > +#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap > + > #endif /* __ASM_IO_H */ > diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c > index b7c81dacabf0..b21f91cd830d 100644 > --- a/arch/arm64/mm/ioremap.c > +++ b/arch/arm64/mm/ioremap.c > @@ -99,3 +99,11 @@ void __init early_ioremap_init(void) > { > early_ioremap_setup(); > } > + > +bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, > + unsigned long flags) > +{ > + unsigned long pfn = PHYS_PFN(offset); > + > + return pfn_is_map_memory(pfn); > +} > diff --git a/kernel/iomem.c b/kernel/iomem.c > index 62c92e43aa0d..e85bed24c0a9 100644 > --- a/kernel/iomem.c > +++ b/kernel/iomem.c > @@ -33,7 +33,7 @@ static void *try_ram_remap(resource_size_t offset, size_t size, > unsigned long pfn = PHYS_PFN(offset); > > /* In the simple case just return the existing linear address */ > - if (pfn_valid(pfn) && !PageHighMem(pfn_to_page(pfn)) && > + if (!PageHighMem(pfn_to_page(pfn)) && This looks wrong to me. Calling any of the PageXxx() accessors is only safe if the PFN is valid, since otherwise, we don't know if the associated struct page exists. > arch_memremap_can_ram_remap(offset, size, flags)) > return __va(offset); > > > base-commit: b2d229d4ddb17db541098b83524d901257e93845 > -- > 2.28.0 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel