OSDN Git Service

Merge branch 'for-next/zone-dma' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorChristoph Hellwig <hch@lst.de>
Thu, 21 Nov 2019 17:13:03 +0000 (18:13 +0100)
committerChristoph Hellwig <hch@lst.de>
Thu, 21 Nov 2019 17:13:03 +0000 (18:13 +0100)
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.

arch/arm64/Kconfig
arch/arm64/mm/init.c
arch/powerpc/include/asm/page.h
arch/powerpc/mm/mem.c
arch/s390/include/asm/page.h
arch/s390/mm/init.c
include/linux/dma-direct.h
include/linux/mmzone.h
kernel/dma/direct.c

index 5760630..ed5706e 100644 (file)
@@ -265,6 +265,10 @@ config GENERIC_CSUM
 config GENERIC_CALIBRATE_DELAY
        def_bool y
 
+config ZONE_DMA
+       bool "Support DMA zone" if EXPERT
+       default y
+
 config ZONE_DMA32
        bool "Support DMA32 zone" if EXPERT
        default y
index 45c00a5..d933589 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sort.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-contiguous.h>
 #include <linux/efi.h>
@@ -41,6 +42,8 @@
 #include <asm/tlb.h>
 #include <asm/alternative.h>
 
+#define ARM64_ZONE_DMA_BITS    30
+
 /*
  * We need to be able to catch inadvertent references to memstart_addr
  * that occur (potentially in generic code) before arm64_memblock_init()
@@ -56,7 +59,14 @@ EXPORT_SYMBOL(physvirt_offset);
 struct page *vmemmap __ro_after_init;
 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;
+static phys_addr_t arm64_dma32_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
 /*
@@ -81,7 +91,7 @@ static void __init reserve_crashkernel(void)
 
        if (crash_base == 0) {
                /* 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);
                if (crash_base == 0) {
                        pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
@@ -169,15 +179,16 @@ static void __init reserve_elfcorehdr(void)
 {
 }
 #endif /* CONFIG_CRASH_DUMP */
+
 /*
- * Return the maximum physical address for ZONE_DMA32 (DMA_BIT_MASK(32)). It
- * currently assumes that for memory starting above 4G, 32-bit devices will
- * use a DMA offset.
+ * Return the maximum physical address for a zone with a given address size
+ * limit. It currently assumes that for memory starting above 4G, 32-bit
+ * 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);
-       return min(offset + (1ULL << 32), memblock_end_of_DRAM());
+       phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
+       return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
 }
 
 #ifdef CONFIG_NUMA
@@ -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};
 
+#ifdef CONFIG_ZONE_DMA
+       max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
+#endif
 #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
        max_zone_pfns[ZONE_NORMAL] = max;
 
@@ -200,16 +214,21 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
        struct memblock_region *reg;
        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));
 
-       /* 4GB maximum for 32-bit only capable devices */
-#ifdef CONFIG_ZONE_DMA32
+#ifdef CONFIG_ZONE_DMA
        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
-       zone_size[ZONE_NORMAL] = max - max_dma;
+       zone_size[ZONE_NORMAL] = max - max_dma32;
 
        memcpy(zhole_size, zone_size, sizeof(zhole_size));
 
@@ -219,16 +238,22 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 
                if (start >= max)
                        continue;
-
-#ifdef CONFIG_ZONE_DMA32
+#ifdef CONFIG_ZONE_DMA
                if (start < max_dma) {
-                       unsigned long dma_end = min(end, max_dma);
-                       zhole_size[ZONE_DMA32] -= dma_end - start;
+                       unsigned long dma_end = min_not_zero(end, max_dma);
+                       zhole_size[ZONE_DMA] -= dma_end - start;
                }
 #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_start = max(start, max_dma);
+                       unsigned long normal_start = max(start, max_dma32);
                        zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
                }
        }
@@ -418,11 +443,15 @@ void __init arm64_memblock_init(void)
 
        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))
-               arm64_dma_phys_limit = max_zone_dma_phys();
+               arm64_dma32_phys_limit = max_zone_phys(32);
        else
-               arm64_dma_phys_limit = PHYS_MASK + 1;
+               arm64_dma32_phys_limit = PHYS_MASK + 1;
 
        reserve_crashkernel();
 
@@ -430,7 +459,7 @@ void __init arm64_memblock_init(void)
 
        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)
@@ -534,7 +563,7 @@ static void __init free_unused_memmap(void)
 void __init mem_init(void)
 {
        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);
        else
                swiotlb_force = SWIOTLB_NO_FORCE;
index c8bb14f..f6c562a 100644 (file)
@@ -329,13 +329,4 @@ struct vm_area_struct;
 #endif /* __ASSEMBLY__ */
 #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 */
index be941d3..c95b7fe 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/memremap.h>
+#include <linux/dma-direct.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
@@ -201,10 +202,10 @@ 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 ARCH_ZONE_DMA_BITS 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.
+ * By using 31-bit unconditionally, we can exploit zone_dma_bits 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.
  */
 static unsigned long max_zone_pfns[MAX_NR_ZONES];
 
@@ -237,9 +238,18 @@ void __init paging_init(void)
        printk(KERN_DEBUG "Memory hole size: %ldMB\n",
               (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
        max_zone_pfns[ZONE_DMA] = min(max_low_pfn,
-                                     1UL << (ARCH_ZONE_DMA_BITS - PAGE_SHIFT));
+                                     1UL << (zone_dma_bits - PAGE_SHIFT));
 #endif
        max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 #ifdef CONFIG_HIGHMEM
index 823578c..a4d3809 100644 (file)
@@ -177,8 +177,6 @@ static inline int devmem_is_allowed(unsigned long pfn)
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define ARCH_ZONE_DMA_BITS     31
-
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
 
index a124f19..f0ce222 100644 (file)
@@ -118,6 +118,7 @@ void __init paging_init(void)
 
        sparse_memory_present_with_active_regions(MAX_NUMNODES);
        sparse_init();
+       zone_dma_bits = 31;
        memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
        max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
        max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
index 99b77dd..452f528 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/memblock.h> /* for min_low_pfn */
 #include <linux/mem_encrypt.h>
 
+extern unsigned int zone_dma_bits;
+
 #ifdef CONFIG_ARCH_HAS_PHYS_TO_DMA
 #include <asm/dma-direct.h>
 #else
index bda2028..b0a36d1 100644 (file)
@@ -359,33 +359,40 @@ struct per_cpu_nodestat {
 #endif /* !__GENERATING_BOUNDS.H */
 
 enum zone_type {
-#ifdef CONFIG_ZONE_DMA
        /*
-        * ZONE_DMA is used when there are devices that are not able
-        * to do DMA to all of addressable memory (ZONE_NORMAL). Then we
-        * carve out the portion of memory that is needed for these devices.
-        * The range is arch specific.
+        * ZONE_DMA and ZONE_DMA32 are used when there are peripherals not able
+        * to DMA to all of the addressable memory (ZONE_NORMAL).
+        * On architectures where this area covers the whole 32 bit address
+        * 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
-        * ---------------------------
-        * parisc, ia64, sparc  <4G
-        * s390, powerpc        <2G
-        * arm                  Various
-        * alpha                Unlimited or 0-16MB.
+        *  - s390 uses ZONE_DMA fixed to the lower 2G.
         *
-        * i386, x86_64 and multiple other arches
-        *                      <16M.
+        *  - ia64 and riscv only use ZONE_DMA32.
+        *
+        *  - parisc uses neither.
         */
+#ifdef CONFIG_ZONE_DMA
        ZONE_DMA,
 #endif
 #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,
 #endif
        /*
index 40f1f0a..267b23a 100644 (file)
 #include <linux/swiotlb.h>
 
 /*
- * Most architectures use ZONE_DMA for the first 16 Megabytes, but
- * some use it for entirely different regions:
+ * Most architectures use ZONE_DMA for the first 16 Megabytes, but some use it
+ * 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
-#define ARCH_ZONE_DMA_BITS 24
-#endif
+unsigned int zone_dma_bits __ro_after_init = 24;
 
 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,
         * Note that GFP_DMA32 and GFP_DMA are no ops without the corresponding
         * zones.
         */
-       if (*phys_mask <= DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
+       if (*phys_mask <= DMA_BIT_MASK(zone_dma_bits))
                return GFP_DMA;
        if (*phys_mask <= DMA_BIT_MASK(32))
                return GFP_DMA32;
@@ -485,7 +484,7 @@ int dma_direct_supported(struct device *dev, u64 mask)
        u64 min_mask;
 
        if (IS_ENABLED(CONFIG_ZONE_DMA))
-               min_mask = DMA_BIT_MASK(ARCH_ZONE_DMA_BITS);
+               min_mask = DMA_BIT_MASK(zone_dma_bits);
        else
                min_mask = DMA_BIT_MASK(32);