diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-23 20:47:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-23 20:47:36 -0400 |
commit | 98de5ab7138bdb78ba1cf50978201a4c21bdb111 (patch) | |
tree | 023a82b35f7841c37b6b7559bfcabfd8fa202357 | |
parent | 29ae8a6a281445ae5fe69287cf1165326978b1c7 (diff) | |
parent | d50314a6b0702c630c35b88148c1acb76d2e4ede (diff) |
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
-rw-r--r-- | arch/arm64/mm/init.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index f43db8a69262..e90c5426fe14 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
@@ -60,6 +60,17 @@ static int __init early_initrd(char *p) | |||
60 | early_param("initrd", early_initrd); | 60 | early_param("initrd", early_initrd); |
61 | #endif | 61 | #endif |
62 | 62 | ||
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 | |||
63 | static void __init zone_sizes_init(unsigned long min, unsigned long max) | 74 | static void __init zone_sizes_init(unsigned long min, unsigned long max) |
64 | { | 75 | { |
65 | struct memblock_region *reg; | 76 | struct memblock_region *reg; |
@@ -70,9 +81,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) | |||
70 | 81 | ||
71 | /* 4GB maximum for 32-bit only capable devices */ | 82 | /* 4GB maximum for 32-bit only capable devices */ |
72 | if (IS_ENABLED(CONFIG_ZONE_DMA)) { | 83 | if (IS_ENABLED(CONFIG_ZONE_DMA)) { |
73 | unsigned long max_dma_phys = | 84 | max_dma = PFN_DOWN(max_zone_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)); | ||
76 | zone_size[ZONE_DMA] = max_dma - min; | 85 | zone_size[ZONE_DMA] = max_dma - min; |
77 | } | 86 | } |
78 | zone_size[ZONE_NORMAL] = max - max_dma; | 87 | zone_size[ZONE_NORMAL] = max - max_dma; |
@@ -146,7 +155,7 @@ void __init arm64_memblock_init(void) | |||
146 | 155 | ||
147 | /* 4GB maximum for 32-bit only capable devices */ | 156 | /* 4GB maximum for 32-bit only capable devices */ |
148 | if (IS_ENABLED(CONFIG_ZONE_DMA)) | 157 | 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(); |
150 | dma_contiguous_reserve(dma_phys_limit); | 159 | dma_contiguous_reserve(dma_phys_limit); |
151 | 160 | ||
152 | memblock_allow_resize(); | 161 | memblock_allow_resize(); |