Commit d7293f79 authored by Christoph Hellwig's avatar Christoph Hellwig

Merge branch 'for-next/zone-dma' of...

Merge branch 'for-next/zone-dma' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux into dma-mapping-for-next

Pull in a stable branch from the arm64 tree that adds the zone_dma_bits
variable to avoid creating hard to resolve conflicts with that addition.
parents 68a33b17 bff3b044
...@@ -265,6 +265,10 @@ config GENERIC_CSUM ...@@ -265,6 +265,10 @@ config GENERIC_CSUM
config GENERIC_CALIBRATE_DELAY config GENERIC_CALIBRATE_DELAY
def_bool y def_bool y
config ZONE_DMA
bool "Support DMA zone" if EXPERT
default y
config ZONE_DMA32 config ZONE_DMA32
bool "Support DMA32 zone" if EXPERT bool "Support DMA32 zone" if EXPERT
default y default y
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/sort.h> #include <linux/sort.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/dma-direct.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h> #include <linux/dma-contiguous.h>
#include <linux/efi.h> #include <linux/efi.h>
...@@ -41,6 +42,8 @@ ...@@ -41,6 +42,8 @@
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/alternative.h> #include <asm/alternative.h>
#define ARM64_ZONE_DMA_BITS 30
/* /*
* We need to be able to catch inadvertent references to memstart_addr * We need to be able to catch inadvertent references to memstart_addr
* that occur (potentially in generic code) before arm64_memblock_init() * that occur (potentially in generic code) before arm64_memblock_init()
...@@ -56,7 +59,14 @@ EXPORT_SYMBOL(physvirt_offset); ...@@ -56,7 +59,14 @@ EXPORT_SYMBOL(physvirt_offset);
struct page *vmemmap __ro_after_init; struct page *vmemmap __ro_after_init;
EXPORT_SYMBOL(vmemmap); EXPORT_SYMBOL(vmemmap);
/*
* We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
* memory as some devices, namely the Raspberry Pi 4, have peripherals with
* this limited view of the memory. ZONE_DMA32 will cover the rest of the 32
* bit addressable memory area.
*/
phys_addr_t arm64_dma_phys_limit __ro_after_init; phys_addr_t arm64_dma_phys_limit __ro_after_init;
static phys_addr_t arm64_dma32_phys_limit __ro_after_init;
#ifdef CONFIG_KEXEC_CORE #ifdef CONFIG_KEXEC_CORE
/* /*
...@@ -81,7 +91,7 @@ static void __init reserve_crashkernel(void) ...@@ -81,7 +91,7 @@ static void __init reserve_crashkernel(void)
if (crash_base == 0) { if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */ /* Current arm64 boot protocol requires 2MB alignment */
crash_base = memblock_find_in_range(0, ARCH_LOW_ADDRESS_LIMIT, crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
crash_size, SZ_2M); crash_size, SZ_2M);
if (crash_base == 0) { if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n", pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
...@@ -169,15 +179,16 @@ static void __init reserve_elfcorehdr(void) ...@@ -169,15 +179,16 @@ static void __init reserve_elfcorehdr(void)
{ {
} }
#endif /* CONFIG_CRASH_DUMP */ #endif /* CONFIG_CRASH_DUMP */
/* /*
* Return the maximum physical address for ZONE_DMA32 (DMA_BIT_MASK(32)). It * Return the maximum physical address for a zone with a given address size
* currently assumes that for memory starting above 4G, 32-bit devices will * limit. It currently assumes that for memory starting above 4G, 32-bit
* use a DMA offset. * devices will use a DMA offset.
*/ */
static phys_addr_t __init max_zone_dma_phys(void) static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
{ {
phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32); phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
return min(offset + (1ULL << 32), memblock_end_of_DRAM()); return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
} }
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
...@@ -186,8 +197,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) ...@@ -186,8 +197,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
{ {
unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; unsigned long max_zone_pfns[MAX_NR_ZONES] = {0};
#ifdef CONFIG_ZONE_DMA
max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
#endif
#ifdef CONFIG_ZONE_DMA32 #ifdef CONFIG_ZONE_DMA32
max_zone_pfns[ZONE_DMA32] = PFN_DOWN(max_zone_dma_phys()); max_zone_pfns[ZONE_DMA32] = PFN_DOWN(arm64_dma32_phys_limit);
#endif #endif
max_zone_pfns[ZONE_NORMAL] = max; max_zone_pfns[ZONE_NORMAL] = max;
...@@ -200,16 +214,21 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) ...@@ -200,16 +214,21 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
{ {
struct memblock_region *reg; struct memblock_region *reg;
unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
unsigned long max_dma = min; unsigned long max_dma32 = min;
unsigned long __maybe_unused max_dma = min;
memset(zone_size, 0, sizeof(zone_size)); memset(zone_size, 0, sizeof(zone_size));
/* 4GB maximum for 32-bit only capable devices */ #ifdef CONFIG_ZONE_DMA
#ifdef CONFIG_ZONE_DMA32
max_dma = PFN_DOWN(arm64_dma_phys_limit); max_dma = PFN_DOWN(arm64_dma_phys_limit);
zone_size[ZONE_DMA32] = max_dma - min; zone_size[ZONE_DMA] = max_dma - min;
max_dma32 = max_dma;
#endif
#ifdef CONFIG_ZONE_DMA32
max_dma32 = PFN_DOWN(arm64_dma32_phys_limit);
zone_size[ZONE_DMA32] = max_dma32 - max_dma;
#endif #endif
zone_size[ZONE_NORMAL] = max - max_dma; zone_size[ZONE_NORMAL] = max - max_dma32;
memcpy(zhole_size, zone_size, sizeof(zhole_size)); memcpy(zhole_size, zone_size, sizeof(zhole_size));
...@@ -219,16 +238,22 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) ...@@ -219,16 +238,22 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
if (start >= max) if (start >= max)
continue; continue;
#ifdef CONFIG_ZONE_DMA
#ifdef CONFIG_ZONE_DMA32
if (start < max_dma) { if (start < max_dma) {
unsigned long dma_end = min(end, max_dma); unsigned long dma_end = min_not_zero(end, max_dma);
zhole_size[ZONE_DMA32] -= dma_end - start; zhole_size[ZONE_DMA] -= dma_end - start;
} }
#endif #endif
if (end > max_dma) { #ifdef CONFIG_ZONE_DMA32
if (start < max_dma32) {
unsigned long dma32_end = min(end, max_dma32);
unsigned long dma32_start = max(start, max_dma);
zhole_size[ZONE_DMA32] -= dma32_end - dma32_start;
}
#endif
if (end > max_dma32) {
unsigned long normal_end = min(end, max); unsigned long normal_end = min(end, max);
unsigned long normal_start = max(start, max_dma); unsigned long normal_start = max(start, max_dma32);
zhole_size[ZONE_NORMAL] -= normal_end - normal_start; zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
} }
} }
...@@ -418,11 +443,15 @@ void __init arm64_memblock_init(void) ...@@ -418,11 +443,15 @@ void __init arm64_memblock_init(void)
early_init_fdt_scan_reserved_mem(); early_init_fdt_scan_reserved_mem();
/* 4GB maximum for 32-bit only capable devices */ if (IS_ENABLED(CONFIG_ZONE_DMA)) {
zone_dma_bits = ARM64_ZONE_DMA_BITS;
arm64_dma_phys_limit = max_zone_phys(ARM64_ZONE_DMA_BITS);
}
if (IS_ENABLED(CONFIG_ZONE_DMA32)) if (IS_ENABLED(CONFIG_ZONE_DMA32))
arm64_dma_phys_limit = max_zone_dma_phys(); arm64_dma32_phys_limit = max_zone_phys(32);
else else
arm64_dma_phys_limit = PHYS_MASK + 1; arm64_dma32_phys_limit = PHYS_MASK + 1;
reserve_crashkernel(); reserve_crashkernel();
...@@ -430,7 +459,7 @@ void __init arm64_memblock_init(void) ...@@ -430,7 +459,7 @@ void __init arm64_memblock_init(void)
high_memory = __va(memblock_end_of_DRAM() - 1) + 1; high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
dma_contiguous_reserve(arm64_dma_phys_limit); dma_contiguous_reserve(arm64_dma32_phys_limit);
} }
void __init bootmem_init(void) void __init bootmem_init(void)
...@@ -534,7 +563,7 @@ static void __init free_unused_memmap(void) ...@@ -534,7 +563,7 @@ static void __init free_unused_memmap(void)
void __init mem_init(void) void __init mem_init(void)
{ {
if (swiotlb_force == SWIOTLB_FORCE || if (swiotlb_force == SWIOTLB_FORCE ||
max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) max_pfn > PFN_DOWN(arm64_dma_phys_limit ? : arm64_dma32_phys_limit))
swiotlb_init(1); swiotlb_init(1);
else else
swiotlb_force = SWIOTLB_NO_FORCE; swiotlb_force = SWIOTLB_NO_FORCE;
......
...@@ -329,13 +329,4 @@ struct vm_area_struct; ...@@ -329,13 +329,4 @@ struct vm_area_struct;
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#include <asm/slice.h> #include <asm/slice.h>
/*
* Allow 30-bit DMA for very limited Broadcom wifi chips on many powerbooks.
*/
#ifdef CONFIG_PPC32
#define ARCH_ZONE_DMA_BITS 30
#else
#define ARCH_ZONE_DMA_BITS 31
#endif
#endif /* _ASM_POWERPC_PAGE_H */ #endif /* _ASM_POWERPC_PAGE_H */
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/memremap.h> #include <linux/memremap.h>
#include <linux/dma-direct.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/prom.h> #include <asm/prom.h>
...@@ -201,10 +202,10 @@ static int __init mark_nonram_nosave(void) ...@@ -201,10 +202,10 @@ 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 ARCH_ZONE_DMA_BITS to * By using 31-bit unconditionally, we can exploit zone_dma_bits to inform the
* inform the generic DMA mapping code. 32-bit only devices (if not handled * generic DMA mapping code. 32-bit only devices (if not handled by an IOMMU
* by an IOMMU anyway) will take a first dip into ZONE_NORMAL and get * anyway) will take a first dip into ZONE_NORMAL and get otherwise served by
* otherwise served by ZONE_DMA. * ZONE_DMA.
*/ */
static unsigned long max_zone_pfns[MAX_NR_ZONES]; static unsigned long max_zone_pfns[MAX_NR_ZONES];
...@@ -237,9 +238,18 @@ void __init paging_init(void) ...@@ -237,9 +238,18 @@ void __init paging_init(void)
printk(KERN_DEBUG "Memory hole size: %ldMB\n", printk(KERN_DEBUG "Memory hole size: %ldMB\n",
(long int)((top_of_ram - total_ram) >> 20)); (long int)((top_of_ram - total_ram) >> 20));
/*
* Allow 30-bit DMA for very limited Broadcom wifi chips on many
* powerbooks.
*/
if (IS_ENABLED(CONFIG_PPC32))
zone_dma_bits = 30;
else
zone_dma_bits = 31;
#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 << (ARCH_ZONE_DMA_BITS - PAGE_SHIFT)); 1UL << (zone_dma_bits - PAGE_SHIFT));
#endif #endif
max_zone_pfns[ZONE_NORMAL] = max_low_pfn; max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
......
...@@ -177,8 +177,6 @@ static inline int devmem_is_allowed(unsigned long pfn) ...@@ -177,8 +177,6 @@ static inline int devmem_is_allowed(unsigned long pfn)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#define ARCH_ZONE_DMA_BITS 31
#include <asm-generic/memory_model.h> #include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h> #include <asm-generic/getorder.h>
......
...@@ -118,6 +118,7 @@ void __init paging_init(void) ...@@ -118,6 +118,7 @@ void __init paging_init(void)
sparse_memory_present_with_active_regions(MAX_NUMNODES); sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init(); sparse_init();
zone_dma_bits = 31;
memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
max_zone_pfns[ZONE_NORMAL] = max_low_pfn; max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/memblock.h> /* for min_low_pfn */ #include <linux/memblock.h> /* for min_low_pfn */
#include <linux/mem_encrypt.h> #include <linux/mem_encrypt.h>
extern unsigned int zone_dma_bits;
#ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
#include <asm/dma-direct.h> #include <asm/dma-direct.h>
#else #else
......
...@@ -359,33 +359,40 @@ struct per_cpu_nodestat { ...@@ -359,33 +359,40 @@ struct per_cpu_nodestat {
#endif /* !__GENERATING_BOUNDS.H */ #endif /* !__GENERATING_BOUNDS.H */
enum zone_type { enum zone_type {
#ifdef CONFIG_ZONE_DMA
/* /*
* ZONE_DMA is used when there are devices that are not able * ZONE_DMA and ZONE_DMA32 are used when there are peripherals not able
* to do DMA to all of addressable memory (ZONE_NORMAL). Then we * to DMA to all of the addressable memory (ZONE_NORMAL).
* carve out the portion of memory that is needed for these devices. * On architectures where this area covers the whole 32 bit address
* The range is arch specific. * space ZONE_DMA32 is used. ZONE_DMA is left for the ones with smaller
* DMA addressing constraints. This distinction is important as a 32bit
* DMA mask is assumed when ZONE_DMA32 is defined. Some 64-bit
* platforms may need both zones as they support peripherals with
* different DMA addressing limitations.
*
* Some examples:
*
* - i386 and x86_64 have a fixed 16M ZONE_DMA and ZONE_DMA32 for the
* rest of the lower 4G.
*
* - arm only uses ZONE_DMA, the size, up to 4G, may vary depending on
* the specific device.
*
* - arm64 has a fixed 1G ZONE_DMA and ZONE_DMA32 for the rest of the
* lower 4G.
* *
* Some examples * - powerpc only uses ZONE_DMA, the size, up to 2G, may vary
* depending on the specific device.
* *
* Architecture Limit * - s390 uses ZONE_DMA fixed to the lower 2G.
* ---------------------------
* parisc, ia64, sparc <4G
* s390, powerpc <2G
* arm Various
* alpha Unlimited or 0-16MB.
* *
* i386, x86_64 and multiple other arches * - ia64 and riscv only use ZONE_DMA32.
* <16M. *
* - parisc uses neither.
*/ */
#ifdef CONFIG_ZONE_DMA
ZONE_DMA, ZONE_DMA,
#endif #endif
#ifdef CONFIG_ZONE_DMA32 #ifdef CONFIG_ZONE_DMA32
/*
* x86_64 needs two ZONE_DMAs because it supports devices that are
* only able to do DMA to the lower 16M but also 32 bit devices that
* can only do DMA areas below 4G.
*/
ZONE_DMA32, ZONE_DMA32,
#endif #endif
/* /*
......
...@@ -17,12 +17,11 @@ ...@@ -17,12 +17,11 @@
#include <linux/swiotlb.h> #include <linux/swiotlb.h>
/* /*
* Most architectures use ZONE_DMA for the first 16 Megabytes, but * Most architectures use ZONE_DMA for the first 16 Megabytes, but some use it
* some use it for entirely different regions: * it for entirely different regions. In that case the arch code needs to
* override the variable below for dma-direct to work properly.
*/ */
#ifndef ARCH_ZONE_DMA_BITS unsigned int zone_dma_bits __ro_after_init = 24;
#define ARCH_ZONE_DMA_BITS 24
#endif
static void report_addr(struct device *dev, dma_addr_t dma_addr, size_t size) static void report_addr(struct device *dev, dma_addr_t dma_addr, size_t size)
{ {
...@@ -76,7 +75,7 @@ static gfp_t __dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, ...@@ -76,7 +75,7 @@ static gfp_t __dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
* Note that GFP_DMA32 and GFP_DMA are no ops without the corresponding * Note that GFP_DMA32 and GFP_DMA are no ops without the corresponding
* zones. * zones.
*/ */
if (*phys_mask <= DMA_BIT_MASK(ARCH_ZONE_DMA_BITS)) if (*phys_mask <= DMA_BIT_MASK(zone_dma_bits))
return GFP_DMA; return GFP_DMA;
if (*phys_mask <= DMA_BIT_MASK(32)) if (*phys_mask <= DMA_BIT_MASK(32))
return GFP_DMA32; return GFP_DMA32;
...@@ -485,7 +484,7 @@ int dma_direct_supported(struct device *dev, u64 mask) ...@@ -485,7 +484,7 @@ int dma_direct_supported(struct device *dev, u64 mask)
u64 min_mask; u64 min_mask;
if (IS_ENABLED(CONFIG_ZONE_DMA)) if (IS_ENABLED(CONFIG_ZONE_DMA))
min_mask = DMA_BIT_MASK(ARCH_ZONE_DMA_BITS); min_mask = DMA_BIT_MASK(zone_dma_bits);
else else
min_mask = DMA_BIT_MASK(32); min_mask = DMA_BIT_MASK(32);
......
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