Skip to content

Commit 8324993

Browse files
Baochen Qiangmszyprow
authored andcommitted
dma-mapping: fix missing clear bdr in check_ram_in_range_map()
As discussed in [1], if 'bdr' is set once, it would never get cleared, hence 0 is always returned. Refactor the range check hunk into a new helper dma_find_range(), which allows 'bdr' to be cleared in each iteration. Link: https://lore.kernel.org/all/64931fac-085b-4ff3-9314-84bac2fa9bdb@quicinc.com/ # [1] Fixes: a409d96 ("dma-mapping: fix dma_addressing_limited() if dma_range_map can't cover all system RAM") Suggested-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com> Link: https://lore.kernel.org/r/20250307030350.69144-1-quic_bqiang@quicinc.com Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
1 parent 2014c95 commit 8324993

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

kernel/dma/direct.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,22 @@ int dma_direct_supported(struct device *dev, u64 mask)
584584
return mask >= phys_to_dma_unencrypted(dev, min_mask);
585585
}
586586

587+
static const struct bus_dma_region *dma_find_range(struct device *dev,
588+
unsigned long start_pfn)
589+
{
590+
const struct bus_dma_region *m;
591+
592+
for (m = dev->dma_range_map; PFN_DOWN(m->size); m++) {
593+
unsigned long cpu_start_pfn = PFN_DOWN(m->cpu_start);
594+
595+
if (start_pfn >= cpu_start_pfn &&
596+
start_pfn - cpu_start_pfn < PFN_DOWN(m->size))
597+
return m;
598+
}
599+
600+
return NULL;
601+
}
602+
587603
/*
588604
* To check whether all ram resource ranges are covered by dma range map
589605
* Returns 0 when further check is needed
@@ -593,20 +609,12 @@ static int check_ram_in_range_map(unsigned long start_pfn,
593609
unsigned long nr_pages, void *data)
594610
{
595611
unsigned long end_pfn = start_pfn + nr_pages;
596-
const struct bus_dma_region *bdr = NULL;
597-
const struct bus_dma_region *m;
598612
struct device *dev = data;
599613

600614
while (start_pfn < end_pfn) {
601-
for (m = dev->dma_range_map; PFN_DOWN(m->size); m++) {
602-
unsigned long cpu_start_pfn = PFN_DOWN(m->cpu_start);
615+
const struct bus_dma_region *bdr;
603616

604-
if (start_pfn >= cpu_start_pfn &&
605-
start_pfn - cpu_start_pfn < PFN_DOWN(m->size)) {
606-
bdr = m;
607-
break;
608-
}
609-
}
617+
bdr = dma_find_range(dev, start_pfn);
610618
if (!bdr)
611619
return 1;
612620

0 commit comments

Comments
 (0)