Calling vmalloc_to_page() on ioremap memory?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ard, Mark, Andrew and others,

AFAIU, commit 029c54b09599573015a5c18dbe59cbdf42742237 ("mm/vmalloc.c:
huge-vmap: fail gracefully on unexpected huge vmap mappings") was
supposed to make vmalloc_to_page() return NULL for pointers not
returned by vmalloc().
But when I call vmalloc_to_page() for the pointer returned by
acpi_os_ioremap() (see the patch below) I see that the resulting
`struct page *` points to unmapped memory:

============================
ACPI: Enabled 2 GPEs in block 00 to 0F
phys: 00000000fed00000, vmalloc: ffffc9000019a000, page:
ffff8800fed00000 [ffffea0003fb4000]
BUG: unable to handle kernel paging request at ffffea0003fb4000
PGD 3f7d5067 P4D 3f7d5067 PUD 3f7d4067 PMD 0
Oops: 0000 [#1] SMP PTI
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.18.0-rc2+ #1325
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/=
2014
RIP: 0010:acpi_os_map_iomem+0x1c5/0x210 ??:?
Code: 00 88 ff ff 4d 89 f8 48 c1 f9 06 4c 89 f6 48 c7 c7 60 5f 01 82
48 c1 e1 0c 48 01 c1 e8 6d 42 70 ff 4d 85 ff 0f 84 14 ff ff ff <49> 8b
37 48 c7 c7 d2 61 01 82 e8 55 42 70 ff e9 00 ff ff ff 48 c7
RSP: 0000:ffff88003e253840 EFLAGS: 00010286
RAX: 000000000000005c RBX: ffff88003d857b80 RCX: ffffffff82245d38
RDX: 0000000000000000 RSI: 0000000000000096 RDI: ffffffff8288e86c
RBP: 00000000fed00000 R08: 00000000000000ae R09: 0000000000000007
R10: 0000000000000000 R11: ffffffff828908ad R12: 0000000000001000
R13: ffffc9000019a000 R14: 00000000fed00000 R15: ffffea0003fb4000
FS:  0000000000000000(0000) GS:ffff88003fc00000(0000) knlGS:000000000000000=
0
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffea0003fb4000 CR3: 000000000220a000 CR4: 00000000000006f0
Call Trace:
 acpi_ex_system_memory_space_handler+0xca/0x19f ??:?
============================

For memory error detection purposes I'm trying to map the addresses
from the vmalloc range to valid struct pages, or at least make sure
there's no struct page for a given address.
Looking up the vmap_area_root rbtree isn't an option, as this must be
done from instrumented code, including interrupt handlers.
I've been trying to employ vmalloc_to_page(), but looks like it
doesn't work for ioremapped addresses.
Is this at all possible?

Patch showing the problem follows. I'm building using GCC 7.1.1 on a
defconfig for x86_64.

--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -279,14 +279,23 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size si=
ze)
 static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned
long pg_sz)
 {
        unsigned long pfn;
+       void __iomem *ret;
+       struct page *page;

        pfn =3D pg_off >> PAGE_SHIFT;
        if (should_use_kmap(pfn)) {
                if (pg_sz > PAGE_SIZE)
                        return NULL;
                return (void __iomem __force *)kmap(pfn_to_page(pfn));
-       } else
-               return acpi_os_ioremap(pg_off, pg_sz);
+       } else {
+               ret =3D acpi_os_ioremap(pg_off, pg_sz);
+               BUG_ON(!is_vmalloc_addr(ret));
+               page =3D vmalloc_to_page(ret);
+               pr_err("phys: %px, vmalloc: %px, page: %px [%px]\n",
pg_off, ret, page_address(page), page);
+               if (page)
+                       pr_err("flags: %d\n", page->flags);
+               return ret;
+       }
 }

Thanks,
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux