Skip to content

Commit 98de5ab

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fix from Catalin Marinas: "Fix arm64 regression introduced by limiting the CMA buffer to ZONE_DMA on platforms where RAM starts above 4GB (and ZONE_DMA becoming 0)" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: Create non-empty ZONE_DMA when DRAM starts above 4GB
2 parents 29ae8a6 + d50314a commit 98de5ab

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

arch/arm64/mm/init.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ static int __init early_initrd(char *p)
6060
early_param("initrd", early_initrd);
6161
#endif
6262

63+
/*
64+
* Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
65+
* currently assumes that for memory starting above 4G, 32-bit devices will
66+
* use a DMA offset.
67+
*/
68+
static phys_addr_t max_zone_dma_phys(void)
69+
{
70+
phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
71+
return min(offset + (1ULL << 32), memblock_end_of_DRAM());
72+
}
73+
6374
static void __init zone_sizes_init(unsigned long min, unsigned long max)
6475
{
6576
struct memblock_region *reg;
@@ -70,9 +81,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
7081

7182
/* 4GB maximum for 32-bit only capable devices */
7283
if (IS_ENABLED(CONFIG_ZONE_DMA)) {
73-
unsigned long max_dma_phys =
74-
(unsigned long)(dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1);
75-
max_dma = max(min, min(max, max_dma_phys >> PAGE_SHIFT));
84+
max_dma = PFN_DOWN(max_zone_dma_phys());
7685
zone_size[ZONE_DMA] = max_dma - min;
7786
}
7887
zone_size[ZONE_NORMAL] = max - max_dma;
@@ -146,7 +155,7 @@ void __init arm64_memblock_init(void)
146155

147156
/* 4GB maximum for 32-bit only capable devices */
148157
if (IS_ENABLED(CONFIG_ZONE_DMA))
149-
dma_phys_limit = dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1;
158+
dma_phys_limit = max_zone_dma_phys();
150159
dma_contiguous_reserve(dma_phys_limit);
151160

152161
memblock_allow_resize();

0 commit comments

Comments
 (0)