mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 16:41:39 +00:00
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.
This commit is contained in:
commit
d7293f79ca
@ -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
|
||||
|
@ -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
|
||||
zone_size[ZONE_NORMAL] = max - max_dma;
|
||||
#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_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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
* Some examples:
|
||||
*
|
||||
* Architecture Limit
|
||||
* ---------------------------
|
||||
* parisc, ia64, sparc <4G
|
||||
* s390, powerpc <2G
|
||||
* arm Various
|
||||
* alpha Unlimited or 0-16MB.
|
||||
* - i386 and x86_64 have a fixed 16M ZONE_DMA and ZONE_DMA32 for the
|
||||
* rest of the lower 4G.
|
||||
*
|
||||
* i386, x86_64 and multiple other arches
|
||||
* <16M.
|
||||
* - 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.
|
||||
*
|
||||
* - powerpc only uses ZONE_DMA, the size, up to 2G, may vary
|
||||
* depending on the specific device.
|
||||
*
|
||||
* - s390 uses ZONE_DMA fixed to the lower 2G.
|
||||
*
|
||||
* - 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
|
||||
/*
|
||||
|
@ -17,12 +17,11 @@
|
||||
#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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user