From patchwork Mon Dec 9 19:13:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Logan Gunthorpe X-Patchwork-Id: 11280103 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 835D4930 for ; Mon, 9 Dec 2019 19:15:01 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3DBF2206D3 for ; Mon, 9 Dec 2019 19:15:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="WGTZ46za" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3DBF2206D3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=deltatee.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Subject:MIME-Version:References: In-Reply-To:Message-Id:Date:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=1j8xKAmcGNTh75t+p5/cmLffTR740KFK4Ur6guA8C/g=; b=WGTZ46zaKBYTN9 72GCBKIkCafr/84o8qN0cyjC6gJBrOCH7wkF+U89ZSmoGHGxlm/kHfhqT1nAL/7eSbxQwgCpuwFeZ N4GsLQBSw+D71pNOWT0uKeMgKHxopfUhybMKQrEDsd4ZNrVco/1qruofVYLbZOf94YFpa3bAFhXli tkYr9Vl2OCFifb1xiTKXdEGbLGpiMdV0PbYhGk3DPTg/Zv1GiEn2RFhoO7vFUyLMJe2KkglFhXwbd B2wnBYWf7iuPbTq8lGTALzOFjZOn6S2bUpnGe4HrfaDfJnhmmHU8OWSajhWR6GWW5HWWWT/rrzu5Y FAEpFSv/H31ctyckLkEg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ieOUm-0008QQ-5z; Mon, 09 Dec 2019 19:15:00 +0000 Received: from ale.deltatee.com ([207.54.116.67]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ieOTs-0007Td-Vf for linux-arm-kernel@lists.infradead.org; Mon, 09 Dec 2019 19:14:07 +0000 Received: from cgy1-donard.priv.deltatee.com ([172.16.1.31]) by ale.deltatee.com with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ieOTl-00025p-6A; Mon, 09 Dec 2019 12:14:04 -0700 Received: from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim 4.92) (envelope-from ) id 1ieOTd-0001Ms-Ju; Mon, 09 Dec 2019 12:13:49 -0700 From: Logan Gunthorpe To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-ia64@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, linux-sh@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-mm@kvack.org, Christoph Hellwig , Dan Williams , Andrew Morton Date: Mon, 9 Dec 2019 12:13:45 -0700 Message-Id: <20191209191346.5197-6-logang@deltatee.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191209191346.5197-1-logang@deltatee.com> References: <20191209191346.5197-1-logang@deltatee.com> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 172.16.1.31 X-SA-Exim-Rcpt-To: linux-arm-kernel@lists.infradead.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-ia64@vger.kernel.org, linux-s390@vger.kernel.org, linux-sh@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-mm@kvack.org, hch@lst.de, dan.j.williams@intel.com, akpm@linux-foundation.org, catalin.marinas@arm.com, benh@kernel.crashing.org, tglx@linutronix.de, bp@alien8.de, dave.hansen@linux.intel.com, will@kernel.org, luto@kernel.org, peterz@infradead.org, logang@deltatee.com, mingo@redhat.com, david@redhat.com, mhocko@suse.com X-SA-Exim-Mail-From: gunthorp@deltatee.com X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on ale.deltatee.com X-Spam-Level: X-Spam-Status: No, score=-6.5 required=5.0 tests=ALL_TRUSTED,BAYES_00, MYRULES_FREE,MYRULES_NO_TEXT autolearn=no autolearn_force=no version=3.4.2 Subject: [PATCH 5/6] mm, memory_hotplug: Provide argument for the pgprot_t in arch_add_memory() X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on ale.deltatee.com) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191209_111405_118101_DCCE5261 X-CRM114-Status: GOOD ( 17.54 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [207.54.116.67 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michal Hocko , David Hildenbrand , Peter Zijlstra , Catalin Marinas , Dave Hansen , Logan Gunthorpe , Ingo Molnar , Borislav Petkov , Andy Lutomirski , Benjamin Herrenschmidt , Thomas Gleixner , Will Deacon Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org devm_memremap_pages() is currently used by the PCI P2PDMA code to create struct page mappings for IO memory. At present, these mappings are created with PAGE_KERNEL which implies setting the PAT bits to be WB. However, on x86, an mtrr register will typically override this and force the cache type to be UC-. In the case firmware doesn't set this register it is effectively WB and will typically result in a machine check exception when it's accessed. Other arches are not currently likely to function correctly seeing they don't have any MTRR registers to fall back on. To solve this, add an argument to arch_add_memory() to explicitly set the pgprot value to a specific value. Of the arches that support MEMORY_HOTPLUG: x86_64, s390 and arm64 is a simple change to pass the pgprot_t down to their respective functions which set up the page tables. For x86_32, set the page tables explicitly using _set_memory_prot() (seeing they are already mapped). For sh, reject anything but PAGE_KERNEL settings -- this should be fine, for now, seeing sh doesn't support ZONE_DEVICE anyway. Cc: Dan Williams Cc: David Hildenbrand Cc: Michal Hocko Signed-off-by: Logan Gunthorpe --- arch/arm64/mm/mmu.c | 4 ++-- arch/ia64/mm/init.c | 5 ++++- arch/powerpc/mm/mem.c | 4 ++-- arch/s390/mm/init.c | 4 ++-- arch/sh/mm/init.c | 5 ++++- arch/x86/mm/init_32.c | 7 ++++++- arch/x86/mm/init_64.c | 4 ++-- include/linux/memory_hotplug.h | 2 +- mm/memory_hotplug.c | 2 +- mm/memremap.c | 2 +- 10 files changed, 25 insertions(+), 14 deletions(-) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 60c929f3683b..48b65272df15 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1050,7 +1050,7 @@ int p4d_free_pud_page(p4d_t *p4d, unsigned long addr) } #ifdef CONFIG_MEMORY_HOTPLUG -int arch_add_memory(int nid, u64 start, u64 size, +int arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions) { int flags = 0; @@ -1059,7 +1059,7 @@ int arch_add_memory(int nid, u64 start, u64 size, flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), - size, PAGE_KERNEL, __pgd_pgtable_alloc, flags); + size, prot, __pgd_pgtable_alloc, flags); return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT, restrictions); diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index bf9df2625bc8..15a1efcecd83 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -669,13 +669,16 @@ mem_init (void) } #ifdef CONFIG_MEMORY_HOTPLUG -int arch_add_memory(int nid, u64 start, u64 size, +int arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; int ret; + if (prot != PAGE_KERNEL) + return -EINVAL; + ret = __add_pages(nid, start_pfn, nr_pages, restrictions); if (ret) printk("%s: Problem encountered in __add_pages() as ret=%d\n", diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 22525d8935ce..a901c2b65801 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -105,7 +105,7 @@ int __weak remove_section_mapping(unsigned long start, unsigned long end) return -ENODEV; } -int __ref arch_add_memory(int nid, u64 start, u64 size, +int __ref arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions) { unsigned long start_pfn = start >> PAGE_SHIFT; @@ -115,7 +115,7 @@ int __ref arch_add_memory(int nid, u64 start, u64 size, resize_hpt_for_hotplug(memblock_phys_mem_size()); start = (unsigned long)__va(start); - rc = create_section_mapping(start, start + size, nid, PAGE_KERNEL); + rc = create_section_mapping(start, start + size, nid, prot); if (rc) { pr_warn("Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n", start, start + size, rc); diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 263ebb074cdd..d3a67d8a1317 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -266,7 +266,7 @@ device_initcall(s390_cma_mem_init); #endif /* CONFIG_CMA */ -int arch_add_memory(int nid, u64 start, u64 size, +int arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions) { unsigned long start_pfn = PFN_DOWN(start); @@ -276,7 +276,7 @@ int arch_add_memory(int nid, u64 start, u64 size, if (WARN_ON_ONCE(restrictions->altmap)) return -EINVAL; - rc = vmem_add_mapping(start, size, PAGE_KERNEL); + rc = vmem_add_mapping(start, size, prot); if (rc) return rc; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index dfdbaa50946e..cf9f788115ff 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -405,13 +405,16 @@ void __init mem_init(void) } #ifdef CONFIG_MEMORY_HOTPLUG -int arch_add_memory(int nid, u64 start, u64 size, +int arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions) { unsigned long start_pfn = PFN_DOWN(start); unsigned long nr_pages = size >> PAGE_SHIFT; int ret; + if (prot != PAGE_KERNEL) + return -EINVAL; + /* We only have ZONE_NORMAL, so this is easy.. */ ret = __add_pages(nid, start_pfn, nr_pages, restrictions); if (unlikely(ret)) diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index d3cdd9137f42..c0fe624eb304 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -852,11 +852,16 @@ void __init mem_init(void) } #ifdef CONFIG_MEMORY_HOTPLUG -int arch_add_memory(int nid, u64 start, u64 size, +int arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + int ret; + + ret = _set_memory_prot(start, nr_pages, prot); + if (ret) + return ret; return __add_pages(nid, start_pfn, nr_pages, restrictions); } diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 65a5093ec97b..c7d170d67b57 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -862,13 +862,13 @@ int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, return ret; } -int arch_add_memory(int nid, u64 start, u64 size, +int arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - init_memory_mapping(start, start + size, PAGE_KERNEL); + init_memory_mapping(start, start + size, prot); return add_pages(nid, start_pfn, nr_pages, restrictions); } diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index f46ea71b4ffd..82e8b3fcebab 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -111,7 +111,7 @@ extern void __online_page_free(struct page *page); extern int try_online_node(int nid); -extern int arch_add_memory(int nid, u64 start, u64 size, +extern int arch_add_memory(int nid, u64 start, u64 size, pgprot_t prot, struct mhp_restrictions *restrictions); extern u64 max_mem_size; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index df570e5c71cc..0a581a344a00 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1035,7 +1035,7 @@ int __ref add_memory_resource(int nid, struct resource *res) new_node = ret; /* call arch's memory hotadd */ - ret = arch_add_memory(nid, start, size, &restrictions); + ret = arch_add_memory(nid, start, size, PAGE_KERNEL, &restrictions); if (ret < 0) goto error; diff --git a/mm/memremap.c b/mm/memremap.c index 03ccbdfeb697..4edcca074e15 100644 --- a/mm/memremap.c +++ b/mm/memremap.c @@ -281,7 +281,7 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid) } error = arch_add_memory(nid, res->start, resource_size(res), - &restrictions); + pgprot, &restrictions); } if (!error) {