Message ID | 70d2c447b6dbf472b8e7fec5804deddc12692aab.1723359916.git.baruch@tkos.co.il (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | dma: support DMA zone starting above 4GB | expand |
On Sun, 11 Aug 2024 10:09:36 +0300 Baruch Siach <baruch@tkos.co.il> wrote: > From: Catalin Marinas <catalin.marinas@arm.com> > > Commit 791ab8b2e3db ("arm64: Ignore any DMA offsets in the > max_zone_phys() calculation") made arm64 DMA/DMA32 zones span the entire > RAM when RAM starts above 32-bits. This breaks hardware with DMA area > that start above 32-bits. But the commit log says that "we haven't > noticed any such hardware". It turns out that such hardware does exist. > > One such platform has RAM starting at 32GB with an internal bus that has > the following DMA limits: > > #address-cells = <2>; > #size-cells = <2>; > dma-ranges = <0x00 0xc0000000 0x08 0x00000000 0x00 0x40000000>; > > That is, devices under this bus see 1GB of DMA range between 3GB-4GB in > their address space. This range is mapped to CPU memory at 32GB-33GB. > With current code DMA allocations for devices under this bus are not > limited to DMA area, leading to run-time allocation failure. > > This commit reinstates DMA zone at the bottom of RAM. The result is DMA > zone that properly reflects the hardware constraints as follows: > > [ 0.000000] Zone ranges: > [ 0.000000] DMA [mem 0x0000000800000000-0x000000083fffffff] > [ 0.000000] DMA32 empty > [ 0.000000] Normal [mem 0x0000000840000000-0x0000000bffffffff] > > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> > [baruch: split off the original patch] > Signed-off-by: Baruch Siach <baruch@tkos.co.il> Note that I'm not an Arm64 maintainer, so the value of my review is limited, but AFAICS this change should work as intended. Reviewed-by: Petr Tesarik <ptesarik@suse.com> Petr T > --- > arch/arm64/mm/init.c | 12 ------------ > 1 file changed, 12 deletions(-) > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c > index c45e2152ca9e..bfb10969cbf0 100644 > --- a/arch/arm64/mm/init.c > +++ b/arch/arm64/mm/init.c > @@ -114,20 +114,8 @@ static void __init arch_reserve_crashkernel(void) > low_size, high); > } > > -/* > - * Return the maximum physical address for a zone given its limit. > - * If DRAM starts above 32-bit, expand the zone to the maximum > - * available memory, otherwise cap it at 32-bit. > - */ > static phys_addr_t __init max_zone_phys(phys_addr_t zone_limit) > { > - phys_addr_t phys_start = memblock_start_of_DRAM(); > - > - if (phys_start > U32_MAX) > - zone_limit = PHYS_ADDR_MAX; > - else if (phys_start > zone_limit) > - zone_limit = U32_MAX; > - > return min(zone_limit, memblock_end_of_DRAM() - 1) + 1; > } >
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index c45e2152ca9e..bfb10969cbf0 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -114,20 +114,8 @@ static void __init arch_reserve_crashkernel(void) low_size, high); } -/* - * Return the maximum physical address for a zone given its limit. - * If DRAM starts above 32-bit, expand the zone to the maximum - * available memory, otherwise cap it at 32-bit. - */ static phys_addr_t __init max_zone_phys(phys_addr_t zone_limit) { - phys_addr_t phys_start = memblock_start_of_DRAM(); - - if (phys_start > U32_MAX) - zone_limit = PHYS_ADDR_MAX; - else if (phys_start > zone_limit) - zone_limit = U32_MAX; - return min(zone_limit, memblock_end_of_DRAM() - 1) + 1; }