Subject: Re: usb zero copy dma handling

From: Oliver Neukum <[email-masked]>
Date: Thu, 08 Aug 2019 12:02:04 +0200

Am Donnerstag, den 08.08.2019, 10:59 +0100 schrieb Russell King - ARM
Linux admin:
> On Thu, Aug 08, 2019 at 10:58:11AM +0200, Greg KH wrote:
> > But the main issue here is what exactly is this "fixing"?  What is wrong
> > with the existing code that non-x86 systems have such a problem with?
> > Shouldn't all of these dma issues be handled by the platform with the
> > remap_pfn_range() call itself?
> 
> remap_pfn_range() takes a PFN.  virt_to_phys() converts a kernel *direct
> mapped* virtual address to a physical address.  That much is fine.
> 
> The question is - what is usbm->mem?  If that is anything other than an
> address returned by kmalloc() or from the normal page allocator, then
> virt_to_phys() will return garbage.
> 
> In other words, if it comes from dma_alloc_coherent(), vmalloc() or
> ioremap(), using virt_to_phys() on it results in garbage.

It comes from usb_alloc_coherent() -> hcd_buffer_alloc() ->
hcd_buffer_alloc()

That function is a bit complicated. so I rather quote than explain:

        if (hcd->localmem_pool)
                return gen_pool_dma_alloc(hcd->localmem_pool, size, dma)

        /* some USB hosts just use PIO */
        if (!IS_ENABLED(CONFIG_HAS_DMA) ||
            !is_device_dma_capable(bus->sysdev)) {
                *dma = ~(dma_addr_t) 0;
                return kmalloc(size, mem_flags);
        }

        for (i = 0; i < HCD_BUFFER_POOLS; i++) {
                if (size <= pool_max[i])
                        return dma_pool_alloc(hcd->pool[i], mem_flags, dma);
        }

        return dma_alloc_coherent(hcd->self.sysdev, size, dma, mem_flags);

	Regards
		Oliver

_______________________________________________
linux-arm-kernel mailing list
[email-masked]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel