From patchwork Tue Apr 9 06:17:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 13621869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 4BF9CCD1284 for ; Tue, 9 Apr 2024 06:18:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jYU5HT6qtJjIuUVUJvkt0QpTmNHFdwxo3VLwmAMqMMU=; b=DuEJHc5zKynEX2 AZ03DsmUCzimFkLQtN0xOMSrLxgYtrwbtpmjWxgSs8Vl0ajaa59H9JLztCFwNRCqDQMCwMqF1pkUd FQlsBij27yzF0sOraXVPRQW1RfDezHJ+5oq7WxSGRKwUwZAW6Dsedd+lDJpII94JCq3xffjtmlt96 n0USupm8rdu32hvEXOjNlfyCzsPw7L/aEExTdC0XbIbLB5fR4Y+glMD/ILswiZ7Yf24Q+ynvH7Dz7 r61SZbry35i4bjjaNKHqDtxAIrrXNDd6JzLaPp4md9iINi8ucUZ4F5z0kDbEvbjN366bbF2SE3n2c O0Oe8mEjEiQ0k+SHY7Rg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4ob-00000000Y9X-1IIa; Tue, 09 Apr 2024 06:18:41 +0000 Received: from mail.tkos.co.il ([84.110.109.230]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oD-00000000Y2W-3gKJ for linux-arm-kernel@lists.infradead.org; Tue, 09 Apr 2024 06:18:21 +0000 Received: from tarshish.tkos.co.il (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.tkos.co.il (Postfix) with ESMTPS id CE478440291; Tue, 9 Apr 2024 09:17:42 +0300 (IDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tkos.co.il; s=default; t=1712643463; bh=FXQtGF6++0LX0KatAYgesfv/8e0GvZUA1g/auC5Ghlc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l5JnLph2+ot8XePK4SlZn31LRIvdmAaMZcFK5/sjmQZa0fNGTUHMFjlW0/7d3LVbG 6E9mcmKmABkUmQQVgsztHBJSky0dfHlvbwiJdCefg2lkVkFKRXEfM6Kb10GdKxuYOO oqa/LzAihcKVRg5EDq3bUKxwy44WPJX8F8tdDWLA40VzuhjYsAZ2kl3WlCo0Zd/Zt8 q6sqhPpzabaPVkBLl4mS0nDFpanR6hC7jLKna7nVn1iSI8KazThuKSJWsa+hhEqqXN VsTdwCwvan+rWMZNA67Q9zdFvAE4D0hKiZmDga7ffpM2gyozW5S24N2y+pRJy3WWEW UDOUVIN+RqIIQ== From: Baruch Siach To: Christoph Hellwig , Marek Szyprowski , Rob Herring , Saravana Kannan , Catalin Marinas , Will Deacon Cc: Baruch Siach , Robin Murphy , iommu@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, =?utf-8?b?UGV0?= =?utf-8?b?ciBUZXNhxZnDrWs=?= , Ramon Fried , Elad Nachman Subject: [PATCH RFC v2 1/5] dma-mapping: replace zone_dma_bits by zone_dma_limit Date: Tue, 9 Apr 2024 09:17:54 +0300 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240408_231818_426476_14CAF26E X-CRM114-Status: GOOD ( 21.33 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Catalin Marinas Hardware DMA limit might not be power of 2. When RAM range starts above 0, say 4GB, DMA limit of 30 bits should end at 5GB. A single high bit can not encode this limit. Use direct phys_addr_t limit address for DMA zone limit. Following commits will add explicit base address to DMA zone. Signed-off-by: Catalin Marinas --- Catalin, This is taken almost verbatim from your email: https://lore.kernel.org/all/ZZ2HnHJV3gdzu1Aj@arm.com/ Would you provide your sign-off? Thanks, baruch --- arch/arm64/mm/init.c | 32 ++++++++++---------------------- arch/powerpc/mm/mem.c | 9 ++++----- arch/s390/mm/init.c | 2 +- include/linux/dma-direct.h | 2 +- kernel/dma/direct.c | 6 +++--- kernel/dma/pool.c | 2 +- kernel/dma/swiotlb.c | 4 ++-- 7 files changed, 22 insertions(+), 35 deletions(-) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 03efd86dce0a..00508c69ca9e 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -113,36 +113,24 @@ static void __init arch_reserve_crashkernel(void) low_size, high); } -/* - * Return the maximum physical address for a zone accessible by the given bits - * limit. If DRAM starts above 32-bit, expand the zone to the maximum - * available memory, otherwise cap it at 32-bit. - */ -static phys_addr_t __init max_zone_phys(unsigned int zone_bits) +static phys_addr_t __init max_zone_phys(phys_addr_t zone_limit) { - phys_addr_t zone_mask = DMA_BIT_MASK(zone_bits); - phys_addr_t phys_start = memblock_start_of_DRAM(); - - if (phys_start > U32_MAX) - zone_mask = PHYS_ADDR_MAX; - else if (phys_start > zone_mask) - zone_mask = U32_MAX; - - return min(zone_mask, memblock_end_of_DRAM() - 1) + 1; + return min(zone_limit, memblock_end_of_DRAM() - 1) + 1; } static void __init zone_sizes_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; - unsigned int __maybe_unused acpi_zone_dma_bits; - unsigned int __maybe_unused dt_zone_dma_bits; - phys_addr_t __maybe_unused dma32_phys_limit = max_zone_phys(32); + phys_addr_t __maybe_unused acpi_zone_dma_limit; + phys_addr_t __maybe_unused dt_zone_dma_limit; + phys_addr_t __maybe_unused dma32_phys_limit = + max_zone_phys(DMA_BIT_MASK(32)); #ifdef CONFIG_ZONE_DMA - acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); - dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL)); - zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits); - arm64_dma_phys_limit = max_zone_phys(zone_dma_bits); + acpi_zone_dma_limit = acpi_iort_dma_get_max_cpu_address(); + dt_zone_dma_limit = of_dma_get_max_cpu_address(NULL); + zone_dma_limit = min(dt_zone_dma_limit, acpi_zone_dma_limit); + arm64_dma_phys_limit = max_zone_phys(zone_dma_limit); max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); #endif #ifdef CONFIG_ZONE_DMA32 diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 3a440004b97d..4d6f575fd354 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -214,7 +214,7 @@ static int __init mark_nonram_nosave(void) * everything else. GFP_DMA32 page allocations automatically fall back to * ZONE_DMA. * - * By using 31-bit unconditionally, we can exploit zone_dma_bits to inform the + * By using 31-bit unconditionally, we can exploit zone_dma_limit to inform the * generic DMA mapping code. 32-bit only devices (if not handled by an IOMMU * anyway) will take a first dip into ZONE_NORMAL and get otherwise served by * ZONE_DMA. @@ -250,13 +250,12 @@ void __init paging_init(void) * powerbooks. */ if (IS_ENABLED(CONFIG_PPC32)) - zone_dma_bits = 30; + zone_dma_limit = DMA_BIT_MASK(30); else - zone_dma_bits = 31; + zone_dma_limit = DMA_BIT_MASK(31); #ifdef CONFIG_ZONE_DMA - max_zone_pfns[ZONE_DMA] = min(max_low_pfn, - 1UL << (zone_dma_bits - PAGE_SHIFT)); + max_zone_pfns[ZONE_DMA] = min(max_low_pfn, zone_dma_limit >> PAGE_SHIFT); #endif max_zone_pfns[ZONE_NORMAL] = max_low_pfn; #ifdef CONFIG_HIGHMEM diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index f6391442c0c2..5feaa60933b7 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -95,7 +95,7 @@ void __init paging_init(void) vmem_map_init(); sparse_init(); - zone_dma_bits = 31; + zone_dma_limit = DMA_BIT_MASK(31); memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); max_zone_pfns[ZONE_DMA] = virt_to_pfn(MAX_DMA_ADDRESS); max_zone_pfns[ZONE_NORMAL] = max_low_pfn; diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h index 3eb3589ff43e..7cf76f1d3239 100644 --- a/include/linux/dma-direct.h +++ b/include/linux/dma-direct.h @@ -12,7 +12,7 @@ #include #include -extern unsigned int zone_dma_bits; +extern phys_addr_t zone_dma_limit; /* * Record the mapping of CPU physical to DMA addresses for a given region. diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 4d543b1e9d57..3b2ebcd4f576 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -20,7 +20,7 @@ * it for entirely different regions. In that case the arch code needs to * override the variable below for dma-direct to work properly. */ -unsigned int zone_dma_bits __ro_after_init = 24; +phys_addr_t zone_dma_limit __ro_after_init = DMA_BIT_MASK(24); static inline dma_addr_t phys_to_dma_direct(struct device *dev, phys_addr_t phys) @@ -59,7 +59,7 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 *phys_limit) * zones. */ *phys_limit = dma_to_phys(dev, dma_limit); - if (*phys_limit <= DMA_BIT_MASK(zone_dma_bits)) + if (*phys_limit <= zone_dma_limit) return GFP_DMA; if (*phys_limit <= DMA_BIT_MASK(32)) return GFP_DMA32; @@ -584,7 +584,7 @@ int dma_direct_supported(struct device *dev, u64 mask) * part of the check. */ if (IS_ENABLED(CONFIG_ZONE_DMA)) - min_mask = min_t(u64, min_mask, DMA_BIT_MASK(zone_dma_bits)); + min_mask = min_t(u64, min_mask, zone_dma_limit); return mask >= phys_to_dma_unencrypted(dev, min_mask); } diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c index d10613eb0f63..410a7b40e496 100644 --- a/kernel/dma/pool.c +++ b/kernel/dma/pool.c @@ -70,7 +70,7 @@ static bool cma_in_zone(gfp_t gfp) /* CMA can't cross zone boundaries, see cma_activate_area() */ end = cma_get_base(cma) + size - 1; if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) - return end <= DMA_BIT_MASK(zone_dma_bits); + return end <= zone_dma_limit; if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) return end <= DMA_BIT_MASK(32); return true; diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 86fe172b5958..96d6eee7d215 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -446,7 +446,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask, if (!remap) io_tlb_default_mem.can_grow = true; if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp_mask & __GFP_DMA)) - io_tlb_default_mem.phys_limit = DMA_BIT_MASK(zone_dma_bits); + io_tlb_default_mem.phys_limit = zone_dma_limit; else if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp_mask & __GFP_DMA32)) io_tlb_default_mem.phys_limit = DMA_BIT_MASK(32); else @@ -625,7 +625,7 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes, } gfp &= ~GFP_ZONEMASK; - if (phys_limit <= DMA_BIT_MASK(zone_dma_bits)) + if (phys_limit <= zone_dma_limit) gfp |= __GFP_DMA; else if (phys_limit <= DMA_BIT_MASK(32)) gfp |= __GFP_DMA32; From patchwork Tue Apr 9 06:17:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 13621870 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 45D3CCD129D for ; Tue, 9 Apr 2024 06:18:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=m8OFqOsHOJNT0COQdaDI7aqhpn9EfpaMuqZEocn0NQw=; b=Ol1j687hPqtq2i wyU+gHmLEc2jy19ZHC+Yr7KXAK5WUPbAsddGPUo2pvQCIfn3RsVbJWkvLJwPt+biYknwn7a1YYIii HmOAIOoR9hX1aK3tsQD47qLjycIR4BHwsIKzeKcTjJaHtyYN1w2OZDeLtFDT8Pj3JukYumHyKidi5 eeR39eAJ9A6BJd4xNLYDW5IxMp3HzKGLYYTxHDBpIrcYcsj6zF0b0z6F7yRmIaqK/TyRuPrUGnSVx a/nK0iJiF7QqhUGUIKYve3b/rLll0mic1cgvXDZz3semm2ZQh2Fs4efXXWfkqSuxrrperyeIOZBcU 5TLKOWsYnARaE7t1WEuQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oe-00000000YBv-1TWk; Tue, 09 Apr 2024 06:18:44 +0000 Received: from golan.tkos.co.il ([84.110.109.230] helo=mail.tkos.co.il) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oE-00000000Y2i-0BZm for linux-arm-kernel@lists.infradead.org; Tue, 09 Apr 2024 06:18:22 +0000 Received: from tarshish.tkos.co.il (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.tkos.co.il (Postfix) with ESMTPS id 3F5CC4402AC; Tue, 9 Apr 2024 09:17:43 +0300 (IDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tkos.co.il; s=default; t=1712643463; bh=EIw24HYGCi1y+d787B1Nwod7ac/kZ5Ydc0E1Leu5myU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n3qLjVAj+4pF4UYTEPUfy6hDZc7RQUJl12cdtSQ67feuraSJIcxEnkhhz7svNCZev WiFYZlsATBak209c0SBVa1hf/ggF4S1N16dWH1g9juf38FTb5MKzO5N4stpAdIfAna XycYLYvSezvjE/+xRKgPwwodUZL59zZpOmzpRgcA8BeKfxbYcgVXPCzwMXLGQnMVtk DlpOc9jsgwHZKnFO4YYjqd/gi7etpfY1VBFuqgqhNIsBfzzBbuDvzQy9zRlq1zfL6E VmsQN9vAyrAP78oOAToGaJR2hb+bhccZVs3Bzit89jiGKrOwxaHmKOAsR2I+1vBZUA 1zf1LjaNsJl3Q== From: Baruch Siach To: Christoph Hellwig , Marek Szyprowski , Rob Herring , Saravana Kannan , Catalin Marinas , Will Deacon Cc: Baruch Siach , Robin Murphy , iommu@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, =?utf-8?b?UGV0?= =?utf-8?b?ciBUZXNhxZnDrWs=?= , Ramon Fried , Elad Nachman Subject: [PATCH RFC v2 2/5] of: get dma area lower limit Date: Tue, 9 Apr 2024 09:17:55 +0300 Message-ID: <230ea13ef8e9f576df849e1b03406184ca890ba8.1712642324.git.baruch@tkos.co.il> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240408_231819_133674_4752B0C8 X-CRM114-Status: GOOD ( 21.01 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org of_dma_get_max_cpu_address() returns the highest CPU address that devices can use for DMA. The implicit assumption is that all CPU addresses below that limit are suitable for DMA. However the 'dma-ranges' property this code uses also encodes a lower limit for DMA that is potentially non zero. Rename to of_dma_get_cpu_limits(), and extend to retrieve also the lower limit for the same 'dma-ranges' property describing the high limit. Update callers of of_dma_get_max_cpu_address(). No functional change intended. Signed-off-by: Baruch Siach --- arch/arm64/mm/init.c | 2 +- drivers/of/address.c | 38 +++++++++++++++++++++++++++----------- drivers/of/unittest.c | 8 ++++---- include/linux/of.h | 11 ++++++++--- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 00508c69ca9e..77e942ca578b 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -128,7 +128,7 @@ static void __init zone_sizes_init(void) #ifdef CONFIG_ZONE_DMA acpi_zone_dma_limit = acpi_iort_dma_get_max_cpu_address(); - dt_zone_dma_limit = of_dma_get_max_cpu_address(NULL); + of_dma_get_cpu_limits(NULL, &dt_zone_dma_limit, NULL); zone_dma_limit = min(dt_zone_dma_limit, acpi_zone_dma_limit); arm64_dma_phys_limit = max_zone_phys(zone_dma_limit); max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); diff --git a/drivers/of/address.c b/drivers/of/address.c index ae46a3605904..ac009b3bb63b 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -964,21 +964,25 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) #endif /* CONFIG_HAS_DMA */ /** - * of_dma_get_max_cpu_address - Gets highest CPU address suitable for DMA + * of_dma_get_cpu_limits - Gets highest CPU address suitable for DMA * @np: The node to start searching from or NULL to start from the root + * @max: Pointer to high address limit or NULL if not needed + * @min: Pointer to low address limit or NULL if not needed * * Gets the highest CPU physical address that is addressable by all DMA masters - * in the sub-tree pointed by np, or the whole tree if NULL is passed. If no - * DMA constrained device is found, it returns PHYS_ADDR_MAX. + * in the sub-tree pointed by np, or the whole tree if @np in NULL. If no + * DMA constrained device is found, @*max is PHYS_ADDR_MAX, and @*low is 0. */ -phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np) +void __init of_dma_get_cpu_limits(struct device_node *np, + phys_addr_t *max, phys_addr_t *min) { phys_addr_t max_cpu_addr = PHYS_ADDR_MAX; struct of_range_parser parser; - phys_addr_t subtree_max_addr; + phys_addr_t min_cpu_addr = 0; struct device_node *child; struct of_range range; const __be32 *ranges; + u64 cpu_start = 0; u64 cpu_end = 0; int len; @@ -988,21 +992,33 @@ phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np) ranges = of_get_property(np, "dma-ranges", &len); if (ranges && len) { of_dma_range_parser_init(&parser, np); - for_each_of_range(&parser, &range) - if (range.cpu_addr + range.size > cpu_end) + for_each_of_range(&parser, &range) { + if (range.cpu_addr + range.size > cpu_end) { cpu_end = range.cpu_addr + range.size - 1; + cpu_start = range.cpu_addr; + } + } - if (max_cpu_addr > cpu_end) + if (max_cpu_addr > cpu_end) { max_cpu_addr = cpu_end; + min_cpu_addr = cpu_start; + } } for_each_available_child_of_node(np, child) { - subtree_max_addr = of_dma_get_max_cpu_address(child); - if (max_cpu_addr > subtree_max_addr) + phys_addr_t subtree_max_addr, subtree_min_addr; + + of_dma_get_cpu_limits(child, &subtree_max_addr, &subtree_min_addr); + if (max_cpu_addr > subtree_max_addr) { max_cpu_addr = subtree_max_addr; + min_cpu_addr = subtree_min_addr; + } } - return max_cpu_addr; + if (max) + *max = max_cpu_addr; + if (min) + *min = min_cpu_addr; } /** diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 6b5c36b6a758..2d632d4ec5b1 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -921,7 +921,7 @@ static void __init of_unittest_changeset(void) #endif } -static void __init of_unittest_dma_get_max_cpu_address(void) +static void __init of_unittest_dma_get_cpu_limits(void) { struct device_node *np; phys_addr_t cpu_addr; @@ -935,9 +935,9 @@ static void __init of_unittest_dma_get_max_cpu_address(void) return; } - cpu_addr = of_dma_get_max_cpu_address(np); + of_dma_get_cpu_limits(np, &cpu_addr, NULL); unittest(cpu_addr == 0x4fffffff, - "of_dma_get_max_cpu_address: wrong CPU addr %pad (expecting %x)\n", + "of_dma_get_cpu_limits: wrong CPU addr %pad (expecting %x)\n", &cpu_addr, 0x4fffffff); } @@ -4109,7 +4109,7 @@ static int __init of_unittest(void) of_unittest_changeset(); of_unittest_parse_interrupts(); of_unittest_parse_interrupts_extended(); - of_unittest_dma_get_max_cpu_address(); + of_unittest_dma_get_cpu_limits(); of_unittest_parse_dma_ranges(); of_unittest_pci_dma_ranges(); of_unittest_bus_ranges(); diff --git a/include/linux/of.h b/include/linux/of.h index a0bedd038a05..7756441d3ce0 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -454,7 +454,8 @@ int of_map_id(struct device_node *np, u32 id, const char *map_name, const char *map_mask_name, struct device_node **target, u32 *id_out); -phys_addr_t of_dma_get_max_cpu_address(struct device_node *np); +void of_dma_get_cpu_limits(struct device_node *np, phys_addr_t *max, + phys_addr_t *min); struct kimage; void *of_kexec_alloc_and_setup_fdt(const struct kimage *image, @@ -880,9 +881,13 @@ static inline int of_map_id(struct device_node *np, u32 id, return -EINVAL; } -static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np) +static inline void of_dma_get_cpu_limits(struct device_node *np, + phys_addr_t *max, phys_addr_t *min) { - return PHYS_ADDR_MAX; + if (max) + *max = PHYS_ADDR_MAX; + if (min) + *min = 0; } static inline const void *of_device_get_match_data(const struct device *dev) From patchwork Tue Apr 9 06:17:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 13621865 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id B1E45CD1284 for ; Tue, 9 Apr 2024 06:18:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QYH2JQ4W29t+Q13rbDalsAziKXXo4Vih3wDmNL6+ius=; b=4byYFJOFAw7YNS EvFnoRKuITx3zuF5wM17WjPgUiy5QihLiS2lDztFgtWQEg8EePVj/gefy3Q9VUWUPe6+rD4uFuW7r i1iNxodyZ1gknT1dyT14bjaUxA+7HWuJS97Mu3O1Ej3/e13Y3gdvnb7CuZWPTO3hGkEmsdViRymdA ArwZW5QqXFGGZdn/13fSSv1lOYrIW1lx2042OdqsIYvJzNHRuTRn4VVEdMXjAnoTM/LRmnFAIOXS4 F3OLA/NLYVpHxh/n8/HisHJHE0ccvTWSH5X2EhDJ/r20En83AJIIRDgvtBkswXhWMb97cdkGwhmU1 +9znmL8hmo+8djrA9dqg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oS-00000000Y6I-3xZt; Tue, 09 Apr 2024 06:18:38 +0000 Received: from guitar.tkos.co.il ([84.110.109.230] helo=mail.tkos.co.il) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oD-00000000Y2j-3liJ for linux-arm-kernel@lists.infradead.org; Tue, 09 Apr 2024 06:18:20 +0000 Received: from tarshish.tkos.co.il (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.tkos.co.il (Postfix) with ESMTPS id E92AA4402AF; Tue, 9 Apr 2024 09:17:43 +0300 (IDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tkos.co.il; s=default; t=1712643464; bh=gBrssBZlXRFpb/uFLqMMzn9TEci+17z5aWBNXa2ngBU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X694B3ZvoBbd8hdHi7EzW+8J3OhjQ3vGjltGuIcjUGUE2fwOJptEAEdfejjw64iAN lijKzF39aagDuh+BBzePRq6AGkXS7wMIDboXTR/qyUZYG1iR9j9UE4FLbS4my6aExL grP8xNQYjxSa+353MHFEkx5KeiJJyzng3Lgxngls4wOIpTyqxeAo3aYtRUotgD1s+b RNnGfxtA9aNNWIO47r3iSmqxFw6TwBTMJsLU7SAtgqv66YixNdry2dmyQ981D42CIR ZrkL6mcP1A3ER8fnpQtJ/cjZInpCjfyeUkRT4Puuvkm3pNUJm2LFMZoHx58lBg0eEA IEQfxVkwMVY+g== From: Baruch Siach To: Christoph Hellwig , Marek Szyprowski , Rob Herring , Saravana Kannan , Catalin Marinas , Will Deacon Cc: Baruch Siach , Robin Murphy , iommu@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, =?utf-8?b?UGV0?= =?utf-8?b?ciBUZXNhxZnDrWs=?= , Ramon Fried , Elad Nachman Subject: [PATCH RFC v2 3/5] of: unittest: add test for of_dma_get_cpu_limits() 'min' param Date: Tue, 9 Apr 2024 09:17:56 +0300 Message-ID: <945ff87c765a461d46f0033fbef422e97f9aede0.1712642324.git.baruch@tkos.co.il> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240408_231818_406488_E4920C5E X-CRM114-Status: GOOD ( 12.55 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Verify that of_dma_get_cpu_limits() sets this new parameter to the expected result. Signed-off-by: Baruch Siach --- drivers/of/unittest.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 2d632d4ec5b1..8fabb445a62a 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -924,7 +924,7 @@ static void __init of_unittest_changeset(void) static void __init of_unittest_dma_get_cpu_limits(void) { struct device_node *np; - phys_addr_t cpu_addr; + phys_addr_t cpu_addr_max, cpu_addr_min; if (!IS_ENABLED(CONFIG_OF_ADDRESS)) return; @@ -935,10 +935,13 @@ static void __init of_unittest_dma_get_cpu_limits(void) return; } - of_dma_get_cpu_limits(np, &cpu_addr, NULL); - unittest(cpu_addr == 0x4fffffff, - "of_dma_get_cpu_limits: wrong CPU addr %pad (expecting %x)\n", - &cpu_addr, 0x4fffffff); + of_dma_get_cpu_limits(np, &cpu_addr_max, &cpu_addr_min); + unittest(cpu_addr_max == 0x4fffffff, + "of_dma_get_cpu_limits: wrong CPU max addr %pad (expecting %x)\n", + &cpu_addr_max, 0x4fffffff); + unittest(cpu_addr_min == 0x40000000, + "of_dma_get_cpu_limits: wrong CPU min addr %pad (expecting %x)\n", + &cpu_addr_min, 0x40000000); } static void __init of_unittest_dma_ranges_one(const char *path, From patchwork Tue Apr 9 06:17:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 13621868 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 7D05FCD129A for ; Tue, 9 Apr 2024 06:18:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=PLPTA70VbK0f1cm1r1xuLuxQGItxqeky8MyPjxiff38=; b=JHGJCZx2ve3EDI RbCfg+L2T3/1DsU4FyUI1djSNq1tsLIURDy5kqlYxC6CX5IVswGpLNVBbKR7uJI8XlkXqiS9CR4ZJ cK0cTCJ3E6zxdl00B4+iD8DR//ZFWKcCXOKhQN/dXzcq0424cNaLwRshA3ezKr+WLWcFfF2VKBcLh 0u+Trx9yOhFWUgRZcwNgKXoNp7kPYsqhCzoMY38GbRls3oJRUPRN8xGEH91Yj5sypNSTJLbg031+d b5B2do+M2/nP2NBzG0KOb5fDK+z+W6gNUaGgaNF0tqbfOa+S1tSjywdwIQJMT4duc98f1y6/qsB3y jVmWICrPcD4VSkFlUNKg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oc-00000000YB2-43FO; Tue, 09 Apr 2024 06:18:43 +0000 Received: from wiki.tkos.co.il ([84.110.109.230] helo=mail.tkos.co.il) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oE-00000000Y31-0C4t for linux-arm-kernel@lists.infradead.org; Tue, 09 Apr 2024 06:18:21 +0000 Received: from tarshish.tkos.co.il (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.tkos.co.il (Postfix) with ESMTPS id 9BB83440317; Tue, 9 Apr 2024 09:17:44 +0300 (IDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tkos.co.il; s=default; t=1712643465; bh=0hgo4O4gn7WmugyfT+01Avn3n1mKMQvAQDRnfRZipYM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QHxxcWbmyQfXE4BxeT+gjPvaPi11vN5dFnOJCh6m6YGFDE6Ayf9vzoDbb3jvclyxE CV+N6wKFW2R2QiAAHIPg0WoSZZCitar4W0XwFxeOCU6Ai2D0ILnBH7bKtmwl1G17dI SPr0H3+mxsawR/qdRsnQdCnOV/VK98dRPCJ809l6+9bN/SvD8QTz0eTB9sXfTF1Ni7 R/Zs0VH2/FkwT+DDYxbE+PCqeb/FK48Sonx6NvR6U5lrErLPSaqzewMWw3lNyhhzyE VNVoE4h+tIMMbffxgZfaLdETp8y05fRfAS+iarX8zrJZJAxr15pEpm6dtoLvfg7ZQr qq+dMKlFlARfw== From: Baruch Siach To: Christoph Hellwig , Marek Szyprowski , Rob Herring , Saravana Kannan , Catalin Marinas , Will Deacon Cc: Baruch Siach , Robin Murphy , iommu@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, =?utf-8?b?UGV0?= =?utf-8?b?ciBUZXNhxZnDrWs=?= , Ramon Fried , Elad Nachman Subject: [PATCH RFC v2 4/5] dma-direct: add base offset to zone_dma_bits Date: Tue, 9 Apr 2024 09:17:57 +0300 Message-ID: <1d7b0d59590aae631b6f0b894257ab961b907b44.1712642324.git.baruch@tkos.co.il> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240408_231819_188473_E1C81C12 X-CRM114-Status: GOOD ( 18.40 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Current code using zone_dma_bits assume that all addresses range in the bits mask are suitable for DMA. For some existing platforms this assumption is not correct. DMA range might have non zero lower limit. Add 'zone_dma_base' for platform code to set base address for DMA zone. Rename the dma_direct_supported() local 'min_mask' variable to better describe its use as limit. Suggested-by: Catalin Marinas Signed-off-by: Baruch Siach --- include/linux/dma-direct.h | 1 + kernel/dma/direct.c | 9 +++++---- kernel/dma/pool.c | 2 +- kernel/dma/swiotlb.c | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h index 7cf76f1d3239..dd0330cbef81 100644 --- a/include/linux/dma-direct.h +++ b/include/linux/dma-direct.h @@ -13,6 +13,7 @@ #include extern phys_addr_t zone_dma_limit; +extern phys_addr_t zone_dma_base; /* * Record the mapping of CPU physical to DMA addresses for a given region. diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 3b2ebcd4f576..92bb241645d6 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -21,6 +21,7 @@ * override the variable below for dma-direct to work properly. */ phys_addr_t zone_dma_limit __ro_after_init = DMA_BIT_MASK(24); +phys_addr_t zone_dma_base __ro_after_init; static inline dma_addr_t phys_to_dma_direct(struct device *dev, phys_addr_t phys) @@ -59,7 +60,7 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 *phys_limit) * zones. */ *phys_limit = dma_to_phys(dev, dma_limit); - if (*phys_limit <= zone_dma_limit) + if (*phys_limit <= zone_dma_base + zone_dma_limit) return GFP_DMA; if (*phys_limit <= DMA_BIT_MASK(32)) return GFP_DMA32; @@ -567,7 +568,7 @@ int dma_direct_mmap(struct device *dev, struct vm_area_struct *vma, int dma_direct_supported(struct device *dev, u64 mask) { - u64 min_mask = (max_pfn - 1) << PAGE_SHIFT; + u64 min_limit = (max_pfn - 1) << PAGE_SHIFT; /* * Because 32-bit DMA masks are so common we expect every architecture @@ -584,8 +585,8 @@ int dma_direct_supported(struct device *dev, u64 mask) * part of the check. */ if (IS_ENABLED(CONFIG_ZONE_DMA)) - min_mask = min_t(u64, min_mask, zone_dma_limit); - return mask >= phys_to_dma_unencrypted(dev, min_mask); + min_limit = min_t(u64, min_limit, zone_dma_base + zone_dma_limit); + return mask >= phys_to_dma_unencrypted(dev, min_limit); } /* diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c index 410a7b40e496..61a86f3d83ae 100644 --- a/kernel/dma/pool.c +++ b/kernel/dma/pool.c @@ -70,7 +70,7 @@ static bool cma_in_zone(gfp_t gfp) /* CMA can't cross zone boundaries, see cma_activate_area() */ end = cma_get_base(cma) + size - 1; if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) - return end <= zone_dma_limit; + return end <= zone_dma_base + zone_dma_limit; if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) return end <= DMA_BIT_MASK(32); return true; diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 96d6eee7d215..814052df07c5 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -446,7 +446,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask, if (!remap) io_tlb_default_mem.can_grow = true; if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp_mask & __GFP_DMA)) - io_tlb_default_mem.phys_limit = zone_dma_limit; + io_tlb_default_mem.phys_limit = zone_dma_base + zone_dma_limit; else if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp_mask & __GFP_DMA32)) io_tlb_default_mem.phys_limit = DMA_BIT_MASK(32); else @@ -625,7 +625,7 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes, } gfp &= ~GFP_ZONEMASK; - if (phys_limit <= zone_dma_limit) + if (phys_limit <= zone_dma_base + zone_dma_limit) gfp |= __GFP_DMA; else if (phys_limit <= DMA_BIT_MASK(32)) gfp |= __GFP_DMA32; From patchwork Tue Apr 9 06:17:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 13621867 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 0B15AC67861 for ; Tue, 9 Apr 2024 06:18:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ApTumlmfDJc1g+HQVGIL1Sh1h9qdHi6uSAS5cq6jPm4=; b=xlWhwU4NN4C5FN qvK4sdlV8mOdz6eoA9i5E36k90W0JS5VP9GPoq/A5PWQcS/gBbpKs2afXkOq2+rMHkylgBR38jeO0 +uOurNL/q81UTgoLIgjcooKuWJttpWwCYOInCZGotm4mw3mJEKe5WMk+b2lf9NWwO6vh1HriArEaq gW8/qhL9nCBCg1WLRCAv8/rtXB4ikNV6/WEcx5Kjz6qen8uc+1xewJ/1zndjnJF1JMSyJMoD4gsnK xobG+BOGsIQ4dxjA20FNp21Ne5HnadWUKyLbI/LG2tJOb/apgqlRoxb+fPFkFDx6grn8JVn98TonO Y7wYx4J7GW+GHtxR0VHg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4of-00000000YCe-3eCg; Tue, 09 Apr 2024 06:18:45 +0000 Received: from mail.tkos.co.il ([84.110.109.230]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1ru4oI-00000000Y4x-1Fbb for linux-arm-kernel@lists.infradead.org; Tue, 09 Apr 2024 06:18:31 +0000 Received: from tarshish.tkos.co.il (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.tkos.co.il (Postfix) with ESMTPS id 48858440459; Tue, 9 Apr 2024 09:17:45 +0300 (IDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tkos.co.il; s=default; t=1712643465; bh=R7K6bnEO9GvrFuZ5cBFijMFOruRQKScFkxZi8ojrTRc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SUexIQz8PPD4zBDvys8qW4vICsMoWwrv/Gnfl1XbfryJUgAXmhmvGF4hBnq0rrs9u dJkOWwvsTTJp49f/96CsJAOe7SVxyJYmn5IBK2tBlDDM4FQfyhOmfOsb7RCYJ7mGFQ Z4pxD5uzbWSNMoTrZSEaMPdDEDESwEICV6BGapb1jO3WPznEXPBWQu8Uyy1eK7bhgh VJ2vFMvDL4Ab8KkyRmwnBkXCZkJWEUa948eREug5DCra0Vd7D1+U+jx3rFF10m0DVj SXe8/7ivvfBvgkUsoa+sOWN7M+3AT9z4tW1kFS6QMaNP60x6miJmpnTgoukgFTIE6O pV1sS2D6zWaJw== From: Baruch Siach To: Christoph Hellwig , Marek Szyprowski , Rob Herring , Saravana Kannan , Catalin Marinas , Will Deacon Cc: Baruch Siach , Robin Murphy , iommu@lists.linux.dev, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org, =?utf-8?b?UGV0?= =?utf-8?b?ciBUZXNhxZnDrWs=?= , Ramon Fried , Elad Nachman Subject: [PATCH RFC v2 5/5] arm64: mm: take DMA zone offset into account Date: Tue, 9 Apr 2024 09:17:58 +0300 Message-ID: <2fa9d7954a99b018a32314b9baab25ba18504f15.1712642324.git.baruch@tkos.co.il> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240408_231823_893093_10327A09 X-CRM114-Status: GOOD ( 14.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Commit 791ab8b2e3db ("arm64: Ignore any DMA offsets in the max_zone_phys() calculation") made DMA/DMA32 zones span the entire RAM when RAM starts above 32-bits. This breaks hardware with DMA area that start above 32-bits. But the commit log says that "we haven't noticed any such hardware". It turns out that such hardware does exist. One such platform has RAM starting at 32GB with an internal bus that has the following DMA limits: #address-cells = <2>; #size-cells = <2>; dma-ranges = <0x00 0xc0000000 0x08 0x00000000 0x00 0x40000000>; Devices under this bus can see 1GB of DMA range between 3GB-4GB in each device address space. This range is mapped to CPU memory at 32GB-33GB. With current code DMA allocations for devices under this bus are not limited to DMA area, leading to run-time allocation failure. Modify 'zone_dma_bits' calculation (via dt_zone_dma_bits) to only cover the actual DMA area starting at 'zone_dma_off'. Use the newly introduced 'min' parameter of of_dma_get_cpu_limits() to set 'zone_dma_off'. DMA32 zone is useless in this configuration, so make its limit the same as the DMA zone when the lower DMA limit is higher than 32-bits. The result is DMA zone that properly reflects the hardware constraints as follows: [ 0.000000] Zone ranges: [ 0.000000] DMA [mem 0x0000000800000000-0x000000083fffffff] [ 0.000000] DMA32 empty [ 0.000000] Normal [mem 0x0000000840000000-0x0000000bffffffff] Suggested-by: Catalin Marinas Signed-off-by: Baruch Siach --- arch/arm64/mm/init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 77e942ca578b..cd283ae0178d 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -128,9 +128,11 @@ static void __init zone_sizes_init(void) #ifdef CONFIG_ZONE_DMA acpi_zone_dma_limit = acpi_iort_dma_get_max_cpu_address(); - of_dma_get_cpu_limits(NULL, &dt_zone_dma_limit, NULL); + of_dma_get_cpu_limits(NULL, &dt_zone_dma_limit, &zone_dma_base); zone_dma_limit = min(dt_zone_dma_limit, acpi_zone_dma_limit); arm64_dma_phys_limit = max_zone_phys(zone_dma_limit); + if (zone_dma_base > U32_MAX) + dma32_phys_limit = arm64_dma_phys_limit; max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); #endif #ifdef CONFIG_ZONE_DMA32