Re: vm_area at addr ffffffffc0800000 is not marked as VM_IOREMAP

Alexei Starovoitov
2024-03-08T03:49:31Z

[-- Attachment #1: Type: text/plain, Size: 1728 bytes --]

On Thu, Mar 7, 2024 at 9:54 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Thu, Mar 7, 2024 at 9:42 AM Miguel Ojeda
> <miguel.ojeda.sandonis@gmail.com> wrote:
> >
> > Hi arm64/bpf/pci,
> >
> > In today's next-20240307 with a defconfig LLVM=1 I am seeing [1] under
> > QEMU virt, i.e. from
> > https://lore.kernel.org/all/20240305030516.41519-2-alexei.starovoitov@gmail.com/
> > applied to the bpf-next tree.
> >
> > Cheers,
> > Miguel
> >
> > [1]
> >
> > [ 0.425177] pci-host-generic 4010000000.pcie: host bridge
> > /pcie@10000000 ranges:
> > [ 0.425886] pci-host-generic 4010000000.pcie: IO
> > 0x003eff0000..0x003effffff -> 0x0000000000
> > [ 0.426534] pci-host-generic 4010000000.pcie: MEM
> > 0x0010000000..0x003efeffff -> 0x0010000000
> > [ 0.426764] pci-host-generic 4010000000.pcie: MEM
> > 0x8000000000..0xffffffffff -> 0x8000000000
> > [ 0.427324] ------------[ cut here ]------------
> > [ 0.427456] vm_area at addr ffffffffc0800000 is not marked as VM_IOREMAP
> > [ 0.427944] WARNING: CPU: 0 PID: 1 at mm/vmalloc.c:315
> > ioremap_page_range+0x25c/0x2bc
>
> Great. Thanks for flagging.
> Looks like this check found some misuse of ioremap_page_range.
>
> Note that without marking the address range as VM_IOREMAP
> the vread_iter() will be bulk reading over IO and might
> cause hard hangs and what not.
> pci drivers need to mark their range as VM_IOREMAP.
> That was the reason for the warning.
>
> I'll try to figure out which piece of code missed passing
> VM_IOREMAP into vm_area.
> I'm not familiar with pci, so help is greatly appreciated.

Ok. I think I figured it out.
Please try the attached patch.

[-- Attachment #2: 0001-mm-Enforce-range-of-ioremap_page_range-when-it-s-ins.patch --]
[-- Type: application/octet-stream, Size: 1933 bytes --]

From b446534f2dc5c48d8ab07c68e79648f42238fef8 Mon Sep 17 00:00:00 2001
From: Alexei Starovoitov <ast@kernel.org>
Date: Thu, 7 Mar 2024 19:41:45 -0800
Subject: [PATCH bpf-next] mm: Enforce range of ioremap_page_range when it's
inside vmalloc range

PCI address range is managed independently from vmalloc range.
Enforce flags and range in ioremap_page_range() only when
the start address is within vmalloc range allocated by get_vm_area().

Fixes: 3e49a866c9dc ("mm: Enforce VM_IOREMAP flag and range in ioremap_page_range.")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
mm/vmalloc.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index e5b8c70950bc..17eb0f974e0f 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -311,16 +311,19 @@ int ioremap_page_range(unsigned long addr, unsigned long end,
int err;

area = find_vm_area((void *)addr);
- if (!area || !(area->flags & VM_IOREMAP)) {
- WARN_ONCE(1, "vm_area at addr %lx is not marked as VM_IOREMAP\n", addr);
- return -EINVAL;
- }
- if (addr != (unsigned long)area->addr ||
- (void *)end != area->addr + get_vm_area_size(area)) {
- WARN_ONCE(1, "ioremap request [%lx,%lx) doesn't match vm_area [%lx, %lx)\n",
- addr, end, (long)area->addr,
- (long)area->addr + get_vm_area_size(area));
- return -ERANGE;
+ if (area) {
+ if (!(area->flags & VM_IOREMAP)) {
+ WARN_ONCE(1, "vm_area at addr %lx is not marked as VM_IOREMAP\n",
+ addr);
+ return -EINVAL;
+ }
+ if (addr != (unsigned long)area->addr ||
+ (void *)end != area->addr + get_vm_area_size(area)) {
+ WARN_ONCE(1, "ioremap request [%lx,%lx) doesn't match vm_area [%lx, %lx)\n",
+ addr, end, (long)area->addr,
+ (long)area->addr + get_vm_area_size(area));
+ return -ERANGE;
+ }
}
err = vmap_range_noflush(addr, end, phys_addr, pgprot_nx(prot),
ioremap_max_page_shift);
--
2.43.0