On Mon, 19 Jan 2009 10:14:11 -0700, Russell King - ARM Linux
<linux@xxxxxxxxxxxxxxxx> wrote:
On Mon, Jan 19, 2009 at 10:07:13AM -0700, Matt Gerassimoff wrote:
On Mon, 19 Jan 2009 09:13:58 -0700, Russell King - ARM Linux
<linux@xxxxxxxxxxxxxxxx> wrote:
>diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
>index 18373f7..9f88dd3 100644
>--- a/arch/arm/mm/ioremap.c
>+++ b/arch/arm/mm/ioremap.c
>@@ -138,7 +138,7 @@ void __check_kvm_seq(struct mm_struct *mm)
> */
> static void unmap_area_sections(unsigned long virt, unsigned long
size)
> {
>- unsigned long addr = virt, end = virt + (size & ~SZ_1M);
>+ unsigned long addr = virt, end = virt + (size & ~(SZ_1M - 1));
> pgd_t *pgd;
> flush_cache_vunmap(addr, end);
>@@ -337,10 +337,7 @@ void __iounmap(volatile void __iomem *io_addr)
> void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
> #ifndef CONFIG_SMP
> struct vm_struct **p, *tmp;
>-#endif
>- unsigned int section_mapping = 0;
>-#ifndef CONFIG_SMP
> /*
> * If this is a section based mapping we need to handle it
> * specially as the VM subsystem does not know how to handle
>@@ -352,11 +349,8 @@ void __iounmap(volatile void __iomem *io_addr)
> for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
> if ((tmp->flags & VM_IOREMAP) && (tmp->addr == addr)) {
> if (tmp->flags & VM_ARM_SECTION_MAPPING) {
>- *p = tmp->next;
> unmap_area_sections((unsigned long)tmp->addr,
> tmp->size);
>- kfree(tmp);
>- section_mapping = 1;
> }
> break;
> }
>@@ -364,7 +358,6 @@ void __iounmap(volatile void __iomem *io_addr)
> write_unlock(&vmlist_lock);
> #endif
>- if (!section_mapping)
>- vunmap(addr);
>+ vunmap(addr);
> }
> EXPORT_SYMBOL(__iounmap);
Before this is even tested. I've went down this path. You will
receive a
ton
of Bad PMD errors. unmap_area_sections() and vunmap() don't play nice
together.
This type of solution will require changes to unmap_area_sections().
Okay, I've just lost interest in persuing this bug any further.
I mis-spoke, the changes required are in remap_area_sections(). They
are not doing proper manipulations to the pmd information. If
remap_area_sections() is fixed, there will be no need for
unmap_area_sections()
as vunmap() will do all the work as far as I can tell.
From that statement you just made, where does that leave us? This in my
estimation
is a MAJOR issue. If you need help testing this, I'll be happy to do so.
It may be
faster for you to create a simple kernel module that ioremap() on module
init and
iounmep() on module exit. Printing the returned virtual address from
ioremap() on
each load will yeild a higher and higher addresses until it returns a NULL
pointer
and kernel OOPS. I'm running on a at91sam9260 and it will fail on about 6
to 10
load/unload cycles of the kernel module. So it happens pretty fast.
--
Matt
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html