in kernel/io_trapped.c [41:104]
int register_trapped_io(struct trapped_io *tiop)
{
struct resource *res;
unsigned long len = 0, flags = 0;
struct page *pages[TRAPPED_PAGES_MAX];
int k, n;
if (unlikely(trapped_io_disable))
return 0;
/* structure must be page aligned */
if ((unsigned long)tiop & (PAGE_SIZE - 1))
goto bad;
for (k = 0; k < tiop->num_resources; k++) {
res = tiop->resource + k;
len += roundup(resource_size(res), PAGE_SIZE);
flags |= res->flags;
}
/* support IORESOURCE_IO _or_ MEM, not both */
if (hweight_long(flags) != 1)
goto bad;
n = len >> PAGE_SHIFT;
if (n >= TRAPPED_PAGES_MAX)
goto bad;
for (k = 0; k < n; k++)
pages[k] = virt_to_page(tiop);
tiop->virt_base = vmap(pages, n, VM_MAP, PAGE_NONE);
if (!tiop->virt_base)
goto bad;
len = 0;
for (k = 0; k < tiop->num_resources; k++) {
res = tiop->resource + k;
pr_info("trapped io 0x%08lx overrides %s 0x%08lx\n",
(unsigned long)(tiop->virt_base + len),
res->flags & IORESOURCE_IO ? "io" : "mmio",
(unsigned long)res->start);
len += roundup(resource_size(res), PAGE_SIZE);
}
tiop->magic = IO_TRAPPED_MAGIC;
INIT_LIST_HEAD(&tiop->list);
spin_lock_irq(&trapped_lock);
#ifdef CONFIG_HAS_IOPORT_MAP
if (flags & IORESOURCE_IO)
list_add(&tiop->list, &trapped_io);
#endif
#ifdef CONFIG_HAS_IOMEM
if (flags & IORESOURCE_MEM)
list_add(&tiop->list, &trapped_mem);
#endif
spin_unlock_irq(&trapped_lock);
return 0;
bad:
pr_warn("unable to install trapped io filter\n");
return -1;
}