On Tue, Jun 21, 2011 at 09:00:49PM +0200, Ariane van der Steldt wrote:
> Hi,
> 
> Bus_dmamem_map has a bug in its error path, where it frees the wrong
> memory in the wrong way. Take this code in sparc64 for example:
> 
>         va = uvm_km_valloc(kernel_map, size);
>         ...
> 
>         TAILQ_FOREACH(m, mlist, pageq) {
> #ifdef DIAGNOSTIC
>                 if (size == 0)
>                         panic("_bus_dmamem_map: size botch");
> #endif
>                 addr = VM_PAGE_TO_PHYS(m);
>                 error = pmap_enter(pmap_kernel(), va, addr | cbit,
>                     VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ |
>                     VM_PROT_WRITE | PMAP_WIRED | PMAP_CANFAIL);
>                 if (error) {
>                         /*
>                          * Clean up after ourselves.
>                          * XXX uvm_wait on WAITOK
>                          */
>                         pmap_update(pmap_kernel());
>                         uvm_km_free(kernel_map, va, ssize);
>                                                 ^^
>                         return (error);
>                 }
>                 va += PAGE_SIZE;
>                 size -= PAGE_SIZE;
>         }
> 
> va is incremented in the loop, therefor the uvm_km_free was the wrong
> address to free.
> Furthermore, the pages that have been mapped in (suppose the error
> occured halfway the loop) will be freed by uvm_km_free.
> 
> The diff below fixes this, for:
> alpha, amd64, arm, aviion, i386, loongson, macppc, mvme{68k,88k,ppc},
> octeon, sgi, socppc, sparc64 and vax.
> 
> Please test on all these architectures.
> Ok?
> -- 
> Ariane

So far so good on my 6xamd64 box.

.... Ken

Reply via email to