Skip to content

Commit

Permalink
IO resources, x86: ioremap sanity check to catch mapping requests exc…
Browse files Browse the repository at this point in the history
…eeding the BAR sizes

Go through the iomem resource tree to check if any of the ioremap()
requests span more than any slot in the iomem resource tree and do
a WARN_ON() if we hit this check.

This will raise a red-flag, if some driver is mapping more than what
is needed. And hopefully identify possible corruptions much earlier.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Suresh Siddha authored and Ingo Molnar committed Sep 26, 2008
1 parent 9a22b6e commit 379daf6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
6 changes: 6 additions & 0 deletions arch/x86/mm/ioremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
if (is_ISA_range(phys_addr, last_addr))
return (__force void __iomem *)phys_to_virt(phys_addr);

/*
* Check if the request spans more than any BAR in the iomem resource
* tree.
*/
WARN_ON(iomem_map_sanity_check(phys_addr, size));

/*
* Don't allow anybody to remap normal RAM that we're using..
*/
Expand Down
1 change: 1 addition & 0 deletions include/linux/ioport.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ extern struct resource * __devm_request_region(struct device *dev,

extern void __devm_release_region(struct device *dev, struct resource *parent,
resource_size_t start, resource_size_t n);
extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);

#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
33 changes: 33 additions & 0 deletions kernel/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,3 +827,36 @@ static int __init reserve_setup(char *str)
}

__setup("reserve=", reserve_setup);

/*
* Check if the requested addr and size spans more than any slot in the
* iomem resource tree.
*/
int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
{
struct resource *p = &iomem_resource;
int err = 0;
loff_t l;

read_lock(&resource_lock);
for (p = p->child; p ; p = r_next(NULL, p, &l)) {
/*
* We can probably skip the resources without
* IORESOURCE_IO attribute?
*/
if (p->start >= addr + size)
continue;
if (p->end < addr)
continue;
if (p->start <= addr && (p->end >= addr + size - 1))
continue;
printk(KERN_WARNING "resource map sanity check conflict: "
"0x%llx 0x%llx 0x%llx 0x%llx %s\n",
addr, addr + size - 1, p->start, p->end, p->name);
err = -1;
break;
}
read_unlock(&resource_lock);

return err;
}

0 comments on commit 379daf6

Please sign in to comment.