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