Skip to content

Commit f9fc279

Browse files
Alexei Starovoitovopsiff
authored andcommitted
mm: Introduce vmap_page_range() to map pages in PCI address space
mainline inclusion from mainline-v6.9-rc1 commit d7bca91 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9CHG1 ioremap_page_range() should be used for ranges within vmalloc range only. The vmalloc ranges are allocated by get_vm_area(). PCI has "resource" allocator that manages PCI_IOBASE, IO_SPACE_LIMIT address range, hence introduce vmap_page_range() to be used exclusively to map pages in PCI address space. Fixes: 3e49a86 ("mm: Enforce VM_IOREMAP flag and range in ioremap_page_range.") Reported-by: Miguel Ojeda <ojeda@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Christoph Hellwig <hch@lst.de> Tested-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/bpf/CANiq72ka4rir+RTN2FQoT=Vvprp_Ao-CvoYEkSNqtSY+RZj+AA@mail.gmail.com (cherry picked from commit d7bca91) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent 37bc762 commit f9fc279

7 files changed

Lines changed: 32 additions & 18 deletions

File tree

arch/arm/mm/ioremap.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ void __init add_static_vm_early(struct static_vm *svm)
111111
int ioremap_page(unsigned long virt, unsigned long phys,
112112
const struct mem_type *mtype)
113113
{
114-
return ioremap_page_range(virt, virt + PAGE_SIZE, phys,
115-
__pgprot(mtype->prot_pte));
114+
return vmap_page_range(virt, virt + PAGE_SIZE, phys,
115+
__pgprot(mtype->prot_pte));
116116
}
117117
EXPORT_SYMBOL(ioremap_page);
118118

@@ -491,8 +491,8 @@ int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
491491
if (res->end > IO_SPACE_LIMIT)
492492
return -EINVAL;
493493

494-
return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
495-
__pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte));
494+
return vmap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
495+
__pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte));
496496
}
497497
EXPORT_SYMBOL(pci_remap_iospace);
498498

arch/loongarch/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode,
518518
}
519519

520520
vaddr = (unsigned long)(PCI_IOBASE + range->io_start);
521-
ioremap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
521+
vmap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
522522

523523
return 0;
524524
}

arch/mips/loongson64/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, resource_size_
188188

189189
vaddr = PCI_IOBASE + range->io_start;
190190

191-
ioremap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
191+
vmap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
192192

193193
return 0;
194194
}

arch/powerpc/kernel/isa-bridge.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ static void remap_isa_base(phys_addr_t pa, unsigned long size)
4646
WARN_ON_ONCE(size & ~PAGE_MASK);
4747

4848
if (slab_is_available()) {
49-
if (ioremap_page_range(ISA_IO_BASE, ISA_IO_BASE + size, pa,
50-
pgprot_noncached(PAGE_KERNEL)))
49+
if (vmap_page_range(ISA_IO_BASE, ISA_IO_BASE + size, pa,
50+
pgprot_noncached(PAGE_KERNEL)))
5151
vunmap_range(ISA_IO_BASE, ISA_IO_BASE + size);
5252
} else {
5353
early_ioremap_range(ISA_IO_BASE, pa, size,

drivers/pci/pci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4322,8 +4322,8 @@ int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
43224322
if (res->end > IO_SPACE_LIMIT)
43234323
return -EINVAL;
43244324

4325-
return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
4326-
pgprot_device(PAGE_KERNEL));
4325+
return vmap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
4326+
pgprot_device(PAGE_KERNEL));
43274327
#else
43284328
/*
43294329
* This architecture does not have memory mapped I/O space,

include/linux/io.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,19 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
2323
#ifdef CONFIG_MMU
2424
int ioremap_page_range(unsigned long addr, unsigned long end,
2525
phys_addr_t phys_addr, pgprot_t prot);
26+
int vmap_page_range(unsigned long addr, unsigned long end,
27+
phys_addr_t phys_addr, pgprot_t prot);
2628
#else
2729
static inline int ioremap_page_range(unsigned long addr, unsigned long end,
2830
phys_addr_t phys_addr, pgprot_t prot)
2931
{
3032
return 0;
3133
}
34+
static inline int vmap_page_range(unsigned long addr, unsigned long end,
35+
phys_addr_t phys_addr, pgprot_t prot)
36+
{
37+
return 0;
38+
}
3239
#endif
3340

3441
/*

mm/vmalloc.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,24 @@ static int vmap_range_noflush(unsigned long addr, unsigned long end,
304304
return err;
305305
}
306306

307+
int vmap_page_range(unsigned long addr, unsigned long end,
308+
phys_addr_t phys_addr, pgprot_t prot)
309+
{
310+
int err;
311+
312+
err = vmap_range_noflush(addr, end, phys_addr, pgprot_nx(prot),
313+
ioremap_max_page_shift);
314+
flush_cache_vmap(addr, end);
315+
if (!err)
316+
err = kmsan_ioremap_page_range(addr, end, phys_addr, prot,
317+
ioremap_max_page_shift);
318+
return err;
319+
}
320+
307321
int ioremap_page_range(unsigned long addr, unsigned long end,
308322
phys_addr_t phys_addr, pgprot_t prot)
309323
{
310324
struct vm_struct *area;
311-
int err;
312325

313326
area = find_vm_area((void *)addr);
314327
if (!area || !(area->flags & VM_IOREMAP)) {
@@ -322,13 +335,7 @@ int ioremap_page_range(unsigned long addr, unsigned long end,
322335
(long)area->addr + get_vm_area_size(area));
323336
return -ERANGE;
324337
}
325-
err = vmap_range_noflush(addr, end, phys_addr, pgprot_nx(prot),
326-
ioremap_max_page_shift);
327-
flush_cache_vmap(addr, end);
328-
if (!err)
329-
err = kmsan_ioremap_page_range(addr, end, phys_addr, prot,
330-
ioremap_max_page_shift);
331-
return err;
338+
return vmap_page_range(addr, end, phys_addr, prot);
332339
}
333340

334341
static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,

0 commit comments

Comments
 (0)