From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_RED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05D81C433E9 for ; Sun, 7 Mar 2021 15:26:05 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 926176510A for ; Sun, 7 Mar 2021 15:26:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 926176510A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linuxfoundation.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 303006B0082; Sun, 7 Mar 2021 10:26:04 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 265E76B0085; Sun, 7 Mar 2021 10:26:04 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 090A86B0087; Sun, 7 Mar 2021 10:26:04 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0129.hostedemail.com [216.40.44.129]) by kanga.kvack.org (Postfix) with ESMTP id D7A7B6B0082 for ; Sun, 7 Mar 2021 10:26:03 -0500 (EST) Received: from smtpin14.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id 9275C180ACC20 for ; Sun, 7 Mar 2021 15:26:03 +0000 (UTC) X-FDA: 77893453806.14.8B1F82E Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by imf27.hostedemail.com (Postfix) with ESMTP id A312A80192EA for ; Sun, 7 Mar 2021 15:26:00 +0000 (UTC) Received: by mail.kernel.org (Postfix) with ESMTPSA id 7C4BD65109; Sun, 7 Mar 2021 15:26:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1615130762; bh=kKpYLvtemizOmTFf3yZ6ZojtYaTrl8A4pixvYlJHA4w=; h=Subject:To:Cc:From:Date:In-Reply-To:From; b=XkVyvjgXI2y8fT/zU8BF88g/czyD5u/SzGKp5yUwTE/lErDEN9+1wfQoNzcgseM0e ZVeEmODt3rEmd8xN9y63sW2QwgDEikvp2KYB7lCmd4NPymE1bpPbmVU4YuVr7mkPvC evlaQXhu+zyK004nLE3mHUuMpQbKiLpfDDb+zlMU= Subject: Patch "arm64: mm: Set ZONE_DMA size based on early IORT scan" has been added to the 5.10-stable tree To: akpm@linux-foundation.org,anshuman.khandual@arm.com,aou@eecs.berkeley.edu,ardb@kernel.org,bhelgaas@google.com,catalin.marinas@arm.com,frowand.list@gmail.com,gregkh@linuxfoundation.org,guohanjun@huawei.com,guro@fb.com,hch@lst.de,jeremy.linton@arm.com,jingxiangfeng@huawei.com,lenb@kernel.org,linux-arm-kernel@lists.infradead.org,linux-mm@kvack.org,linux-riscv@lists.infradead.org,lorenzo.pieralisi@arm.com,nsaenzjulienne@suse.de,palmer@dabbelt.com,paul.walmsley@sifive.com,rjw@rjwysocki.net,robh+dt@kernel.org,robin.murphy@arm.com,rppt@kernel.org,song.bao.hua@hisilicon.com,sudeep.holla@arm.com,wangkefeng.wang@huawei.com,will@kernel.org Cc: From: Date: Sun, 07 Mar 2021 16:25:45 +0100 In-Reply-To: <20210303073319.2215839-7-jingxiangfeng@huawei.com> Message-ID: <1615130745103152@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 X-stable: commit X-Patchwork-Hint: ignore X-Stat-Signature: n75d48m5fq31eenytjcp7a9fkwfwb83y X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: A312A80192EA Received-SPF: none (linuxfoundation.org>: No applicable sender policy available) receiver=imf27; identity=mailfrom; envelope-from=""; helo=mail.kernel.org; client-ip=198.145.29.99 X-HE-DKIM-Result: pass/pass X-HE-Tag: 1615130760-412183 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This is a note to let you know that I've just added the patch titled arm64: mm: Set ZONE_DMA size based on early IORT scan to the 5.10-stable tree which can be found at: http://www.kernel.org/git/?p=3Dlinux/kernel/git/stable/stable-queue.g= it;a=3Dsummary The filename of the patch is: arm64-mm-set-zone_dma-size-based-on-early-iort-scan.patch and it can be found in the queue-5.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >From foo@baz Sun Mar 7 04:22:37 PM CET 2021 From: Jing Xiangfeng Date: Wed, 3 Mar 2021 15:33:18 +0800 Subject: arm64: mm: Set ZONE_DMA size based on early IORT scan To: , , , , , , , , , , , , , , , , , , , Cc: , , , , , , , , , Jeremy Linton , Christoph Hellwig , Robin Murphy Message-ID: <20210303073319.2215839-7-jingxiangfeng@huawei.com> From: Ard Biesheuvel commit 2b8652936f0ca9ca2e6c984ae76c7bfcda1b3f22 upstream We recently introduced a 1 GB sized ZONE_DMA to cater for platforms incorporating masters that can address less than 32 bits of DMA, in particular the Raspberry Pi 4, which has 4 or 8 GB of DRAM, but has peripherals that can only address up to 1 GB (and its PCIe host bridge can only access the bottom 3 GB) Instructing the DMA layer about these limitations is straight-forward, even though we had to fix some issues regarding memory limits set in the IORT for named components, and regarding the handling of ACPI _DMA methods. However, the DMA layer also needs to be able to allocate memory that is guaranteed to meet those DMA constraints, for bounce buffering as well as allocating the backing for consistent mappings. This is why the 1 GB ZONE_DMA was introduced recently. Unfortunately, it turns out the having a 1 GB ZONE_DMA as well as a ZONE_DMA32 causes problems with kdump, and potentially in other places where allocations cannot cross zone boundaries. Therefore, we should avoid having two separate DMA zones when possible. So let's do an early scan of the IORT, and only create the ZONE_DMA if we encounter any devices that need it. This puts the burden on the firmware to describe such limitations in the IORT, which may be redundant (and less precise) if _DMA methods are also being provided. However, it should be noted that this situation is highly unusual for arm64 ACPI machines. Also, the DMA subsystem still gives precedence to the _DMA method if implemented, and so we will not lose the ability to perform streaming DMA outside the ZONE_DMA if the _DMA method permits it. [nsaenz: unified implementation with DT's counterpart] Signed-off-by: Ard Biesheuvel Signed-off-by: Nicolas Saenz Julienne Tested-by: Jeremy Linton Acked-by: Lorenzo Pieralisi Acked-by: Hanjun Guo Cc: Jeremy Linton Cc: Lorenzo Pieralisi Cc: Nicolas Saenz Julienne Cc: Rob Herring Cc: Christoph Hellwig Cc: Robin Murphy Cc: Hanjun Guo Cc: Sudeep Holla Cc: Anshuman Khandual Link: https://lore.kernel.org/r/20201119175400.9995-7-nsaenzjulienne@suse= .de Signed-off-by: Catalin Marinas Cc: Signed-off-by: Jing Xiangfeng Signed-off-by: Greg Kroah-Hartman --- arch/arm64/mm/init.c | 5 +++- drivers/acpi/arm64/iort.c | 55 +++++++++++++++++++++++++++++++++++++++= +++++++ include/linux/acpi_iort.h | 4 +++ 3 files changed, 63 insertions(+), 1 deletion(-) --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -29,6 +29,7 @@ #include #include #include +#include =20 #include #include @@ -186,11 +187,13 @@ static phys_addr_t __init max_zone_phys( static void __init zone_sizes_init(unsigned long min, unsigned long max) { unsigned long max_zone_pfns[MAX_NR_ZONES] =3D {0}; + unsigned int __maybe_unused acpi_zone_dma_bits; unsigned int __maybe_unused dt_zone_dma_bits; =20 #ifdef CONFIG_ZONE_DMA + acpi_zone_dma_bits =3D fls64(acpi_iort_dma_get_max_cpu_address()); dt_zone_dma_bits =3D fls64(of_dma_get_max_cpu_address(NULL)); - zone_dma_bits =3D min(32U, dt_zone_dma_bits); + zone_dma_bits =3D min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits); arm64_dma_phys_limit =3D max_zone_phys(zone_dma_bits); max_zone_pfns[ZONE_DMA] =3D PFN_DOWN(arm64_dma_phys_limit); #endif --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -1730,3 +1730,58 @@ void __init acpi_iort_init(void) =20 iort_init_platform_devices(); } + +#ifdef CONFIG_ZONE_DMA +/* + * Extract the highest CPU physical address accessible to all DMA master= s in + * the system. PHYS_ADDR_MAX is returned when no constrained device is f= ound. + */ +phys_addr_t __init acpi_iort_dma_get_max_cpu_address(void) +{ + phys_addr_t limit =3D PHYS_ADDR_MAX; + struct acpi_iort_node *node, *end; + struct acpi_table_iort *iort; + acpi_status status; + int i; + + if (acpi_disabled) + return limit; + + status =3D acpi_get_table(ACPI_SIG_IORT, 0, + (struct acpi_table_header **)&iort); + if (ACPI_FAILURE(status)) + return limit; + + node =3D ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->node_offset); + end =3D ACPI_ADD_PTR(struct acpi_iort_node, iort, iort->header.length); + + for (i =3D 0; i < iort->node_count; i++) { + if (node >=3D end) + break; + + switch (node->type) { + struct acpi_iort_named_component *ncomp; + struct acpi_iort_root_complex *rc; + phys_addr_t local_limit; + + case ACPI_IORT_NODE_NAMED_COMPONENT: + ncomp =3D (struct acpi_iort_named_component *)node->node_data; + local_limit =3D DMA_BIT_MASK(ncomp->memory_address_limit); + limit =3D min_not_zero(limit, local_limit); + break; + + case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: + if (node->revision < 1) + break; + + rc =3D (struct acpi_iort_root_complex *)node->node_data; + local_limit =3D DMA_BIT_MASK(rc->memory_address_limit); + limit =3D min_not_zero(limit, local_limit); + break; + } + node =3D ACPI_ADD_PTR(struct acpi_iort_node, node, node->length); + } + acpi_put_table(&iort->header); + return limit; +} +#endif --- a/include/linux/acpi_iort.h +++ b/include/linux/acpi_iort.h @@ -38,6 +38,7 @@ void iort_dma_setup(struct device *dev, const struct iommu_ops *iort_iommu_configure_id(struct device *dev, const u32 *id_in); int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head= *head); +phys_addr_t acpi_iort_dma_get_max_cpu_address(void); #else static inline void acpi_iort_init(void) { } static inline u32 iort_msi_map_id(struct device *dev, u32 id) @@ -55,6 +56,9 @@ static inline const struct iommu_ops *io static inline int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head= *head) { return 0; } + +static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void) +{ return PHYS_ADDR_MAX; } #endif =20 #endif /* __ACPI_IORT_H__ */ Patches currently in stable-queue which might be from jingxiangfeng@huawe= i.com are queue-5.10/of-unittest-add-test-for-of_dma_get_max_cpu_address.patch queue-5.10/mm-remove-examples-from-enum-zone_type-comment.patch queue-5.10/arm64-mm-set-zone_dma-size-based-on-devicetree-s-dma-ranges.pa= tch queue-5.10/of-address-introduce-of_dma_get_max_cpu_address.patch queue-5.10/arm64-mm-move-zone_dma_bits-initialization-into-zone_sizes_ini= t.patch queue-5.10/arm64-mm-set-zone_dma-size-based-on-early-iort-scan.patch queue-5.10/arm64-mm-move-reserve_crashkernel-into-mem_init.patch