Commit ba0fb44a authored by Catalin Marinas's avatar Catalin Marinas Committed by Christoph Hellwig

dma-mapping: replace zone_dma_bits by zone_dma_limit

The 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 a plain  address for the DMA zone limit instead.

Since the DMA zone can now potentially span beyond 4GB physical limit of
DMA32, make sure to use DMA zone for GFP_DMA32 allocations in that case.
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Co-developed-by: default avatarBaruch Siach <baruch@tkos.co.il>
Signed-off-by: default avatarBaruch Siach <baruch@tkos.co.il>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Reviewed-by: default avatarPetr Tesarik <ptesarik@suse.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent fa3c109a
...@@ -115,35 +115,35 @@ static void __init arch_reserve_crashkernel(void) ...@@ -115,35 +115,35 @@ static void __init arch_reserve_crashkernel(void)
} }
/* /*
* Return the maximum physical address for a zone accessible by the given bits * Return the maximum physical address for a zone given its limit.
* limit. If DRAM starts above 32-bit, expand the zone to the maximum * If DRAM starts above 32-bit, expand the zone to the maximum
* available memory, otherwise cap it at 32-bit. * 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(); phys_addr_t phys_start = memblock_start_of_DRAM();
if (phys_start > U32_MAX) if (phys_start > U32_MAX)
zone_mask = PHYS_ADDR_MAX; zone_limit = PHYS_ADDR_MAX;
else if (phys_start > zone_mask) else if (phys_start > zone_limit)
zone_mask = U32_MAX; zone_limit = 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) static void __init zone_sizes_init(void)
{ {
unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; unsigned long max_zone_pfns[MAX_NR_ZONES] = {0};
unsigned int __maybe_unused acpi_zone_dma_bits; phys_addr_t __maybe_unused acpi_zone_dma_limit;
unsigned int __maybe_unused dt_zone_dma_bits; phys_addr_t __maybe_unused dt_zone_dma_limit;
phys_addr_t __maybe_unused dma32_phys_limit = max_zone_phys(32); phys_addr_t __maybe_unused dma32_phys_limit =
max_zone_phys(DMA_BIT_MASK(32));
#ifdef CONFIG_ZONE_DMA #ifdef CONFIG_ZONE_DMA
acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address()); acpi_zone_dma_limit = acpi_iort_dma_get_max_cpu_address();
dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL)); dt_zone_dma_limit = of_dma_get_max_cpu_address(NULL);
zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits); zone_dma_limit = min(dt_zone_dma_limit, acpi_zone_dma_limit);
arm64_dma_phys_limit = max_zone_phys(zone_dma_bits); arm64_dma_phys_limit = max_zone_phys(zone_dma_limit);
max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit); max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
#endif #endif
#ifdef CONFIG_ZONE_DMA32 #ifdef CONFIG_ZONE_DMA32
......
...@@ -216,7 +216,7 @@ static int __init mark_nonram_nosave(void) ...@@ -216,7 +216,7 @@ static int __init mark_nonram_nosave(void)
* everything else. GFP_DMA32 page allocations automatically fall back to * everything else. GFP_DMA32 page allocations automatically fall back to
* ZONE_DMA. * 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 * 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 * anyway) will take a first dip into ZONE_NORMAL and get otherwise served by
* ZONE_DMA. * ZONE_DMA.
...@@ -230,6 +230,7 @@ void __init paging_init(void) ...@@ -230,6 +230,7 @@ void __init paging_init(void)
{ {
unsigned long long total_ram = memblock_phys_mem_size(); unsigned long long total_ram = memblock_phys_mem_size();
phys_addr_t top_of_ram = memblock_end_of_DRAM(); phys_addr_t top_of_ram = memblock_end_of_DRAM();
int zone_dma_bits;
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
unsigned long v = __fix_to_virt(FIX_KMAP_END); unsigned long v = __fix_to_virt(FIX_KMAP_END);
...@@ -256,6 +257,8 @@ void __init paging_init(void) ...@@ -256,6 +257,8 @@ void __init paging_init(void)
else else
zone_dma_bits = 31; zone_dma_bits = 31;
zone_dma_limit = DMA_BIT_MASK(zone_dma_bits);
#ifdef CONFIG_ZONE_DMA #ifdef CONFIG_ZONE_DMA
max_zone_pfns[ZONE_DMA] = min(max_low_pfn, max_zone_pfns[ZONE_DMA] = min(max_low_pfn,
1UL << (zone_dma_bits - PAGE_SHIFT)); 1UL << (zone_dma_bits - PAGE_SHIFT));
......
...@@ -97,7 +97,7 @@ void __init paging_init(void) ...@@ -97,7 +97,7 @@ void __init paging_init(void)
vmem_map_init(); vmem_map_init();
sparse_init(); sparse_init();
zone_dma_bits = 31; zone_dma_limit = DMA_BIT_MASK(31);
memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
max_zone_pfns[ZONE_DMA] = virt_to_pfn(MAX_DMA_ADDRESS); max_zone_pfns[ZONE_DMA] = virt_to_pfn(MAX_DMA_ADDRESS);
max_zone_pfns[ZONE_NORMAL] = max_low_pfn; max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <linux/mem_encrypt.h> #include <linux/mem_encrypt.h>
#include <linux/swiotlb.h> #include <linux/swiotlb.h>
extern unsigned int zone_dma_bits; extern u64 zone_dma_limit;
/* /*
* Record the mapping of CPU physical to DMA addresses for a given region. * Record the mapping of CPU physical to DMA addresses for a given region.
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* it for entirely different regions. In that case the arch code needs to * it for entirely different regions. In that case the arch code needs to
* override the variable below for dma-direct to work properly. * override the variable below for dma-direct to work properly.
*/ */
unsigned int zone_dma_bits __ro_after_init = 24; u64 zone_dma_limit __ro_after_init = DMA_BIT_MASK(24);
static inline dma_addr_t phys_to_dma_direct(struct device *dev, static inline dma_addr_t phys_to_dma_direct(struct device *dev,
phys_addr_t phys) phys_addr_t phys)
...@@ -59,7 +59,7 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 *phys_limit) ...@@ -59,7 +59,7 @@ static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 *phys_limit)
* zones. * zones.
*/ */
*phys_limit = dma_to_phys(dev, dma_limit); *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; return GFP_DMA;
if (*phys_limit <= DMA_BIT_MASK(32)) if (*phys_limit <= DMA_BIT_MASK(32))
return GFP_DMA32; return GFP_DMA32;
...@@ -580,7 +580,7 @@ int dma_direct_supported(struct device *dev, u64 mask) ...@@ -580,7 +580,7 @@ int dma_direct_supported(struct device *dev, u64 mask)
* part of the check. * part of the check.
*/ */
if (IS_ENABLED(CONFIG_ZONE_DMA)) 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); return mask >= phys_to_dma_unencrypted(dev, min_mask);
} }
......
...@@ -70,9 +70,9 @@ static bool cma_in_zone(gfp_t gfp) ...@@ -70,9 +70,9 @@ static bool cma_in_zone(gfp_t gfp)
/* CMA can't cross zone boundaries, see cma_activate_area() */ /* CMA can't cross zone boundaries, see cma_activate_area() */
end = cma_get_base(cma) + size - 1; end = cma_get_base(cma) + size - 1;
if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) 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)) if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32))
return end <= DMA_BIT_MASK(32); return end <= max(DMA_BIT_MASK(32), zone_dma_limit);
return true; return true;
} }
......
...@@ -450,9 +450,9 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask, ...@@ -450,9 +450,9 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
if (!remap) if (!remap)
io_tlb_default_mem.can_grow = true; io_tlb_default_mem.can_grow = true;
if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp_mask & __GFP_DMA)) 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)) else if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp_mask & __GFP_DMA32))
io_tlb_default_mem.phys_limit = DMA_BIT_MASK(32); io_tlb_default_mem.phys_limit = max(DMA_BIT_MASK(32), zone_dma_limit);
else else
io_tlb_default_mem.phys_limit = virt_to_phys(high_memory - 1); io_tlb_default_mem.phys_limit = virt_to_phys(high_memory - 1);
#endif #endif
...@@ -629,7 +629,7 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes, ...@@ -629,7 +629,7 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,
} }
gfp &= ~GFP_ZONEMASK; gfp &= ~GFP_ZONEMASK;
if (phys_limit <= DMA_BIT_MASK(zone_dma_bits)) if (phys_limit <= zone_dma_limit)
gfp |= __GFP_DMA; gfp |= __GFP_DMA;
else if (phys_limit <= DMA_BIT_MASK(32)) else if (phys_limit <= DMA_BIT_MASK(32))
gfp |= __GFP_DMA32; gfp |= __GFP_DMA32;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment