RE: [PATCH 6/8] xhci: remove GFP_DMA flag from allocation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mathias Nyman
> Sent: 19 May 2017 10:49
> To: David Laight; gregkh@xxxxxxxxxxxxxxxxxxx
> Cc: linux-usb@xxxxxxxxxxxxxxx; Matthias Lange; stable@xxxxxxxxxxxxxxx
> Subject: Re: [PATCH 6/8] xhci: remove GFP_DMA flag from allocation
> 
> On 19.05.2017 12:10, David Laight wrote:
> > From: Mathias Nyman
> >> Sent: 17 May 2017 16:32
> >> There is no reason to restrict allocations to the first 16MB ISA DMA
> >> addresses.
> >>
> >> It is causing problems in a virtualization setup with enabled IOMMU
> >> (x86_64). The result is that USB is not working in the VM.
> > ...
> >> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> >> index 12b573c..1f1687e 100644
> >> --- a/drivers/usb/host/xhci-mem.c
> >> +++ b/drivers/usb/host/xhci-mem.c
> >> @@ -56,7 +56,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,
> >>   	}
> >>
> >>   	if (max_packet) {
> >> -		seg->bounce_buf = kzalloc(max_packet, flags | GFP_DMA);
> >> +		seg->bounce_buf = kzalloc(max_packet, flags);
> >
> > This might allocate memory that the device cannot access.
> > So can only work if dma_map_single() itself allocates a bounce buffer.
> > There must be a sane way to do this that doesn't ever require
> > double copies.
> >
> 
> We are using dma_map_single()
> This allocated memory is used as the processor virtual memory required by dma_map_single()
> i.e. the "void *cpu_addr" part of dma_map_single, see DMA-API.txt:
> 
> 
> dma_map_single(struct device *dev, void *cpu_addr, size_t size,
>                        enum dma_data_direction direction)
> 
> Maps a piece of processor virtual memory so it can be accessed by the
> device and returns the DMA address of the memory.
> 
> ...
> 
> Notes:  Not all memory regions in a machine can be mapped by this API.
> Further, contiguous kernel virtual space may not be contiguous as
> physical memory.  Since this API does not provide any scatter/gather
> capability, it will fail if the user tries to map a non-physically
> contiguous piece of memory.  For this reason, memory to be mapped by
> this API should be obtained from sources which guarantee it to be
> physically contiguous (like kmalloc).
> 
> I'm not fully sure I understand yout concern, are you thinking the driver should
> doublecheck the dma address returned by dma_map_single() and make sure it's within the
> dma mask set for the device?

The physical memory returned by kzalloc() (without GFP_DMA) can definitely be
outside the dma mask for the device.
If that happens something must allocate a dma bounce buffer, I'm guessing that
dma_map_single() does so - it certainly can since it can copy the data during
the unmap (for a read transfer).
So you really want to allocate a buffer that is within the devices dma window.

The buffer you are allocating isn't really a 'bounce' buffer at all - is it?
It is more of a de_fragmentation buffer.
It is there so that the LINK TRB will always be at a USB segment boundary.
(I'm guessing the bug I found several years ago still isn't fixed??)

	David




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]