diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-11-05 15:50:03 +0100 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2014-03-05 00:38:14 +0100 |
commit | 84c1e40fd794a883431fc7688f653d3faa0265f0 (patch) | |
tree | 20a93c606bf709a6a364ff3b25945c63ecbac8af /drivers/usb/host/xhci-mem.c | |
parent | xhci: xhci_mem_cleanup: make sure cmd_ring_reserved_trbs really is 0 (diff) | |
download | linux-84c1e40fd794a883431fc7688f653d3faa0265f0.tar.xz linux-84c1e40fd794a883431fc7688f653d3faa0265f0.zip |
xhci: The trb_address_map radix tree expects 1KB segment memory aligment
If we align segment dma pool memory to 64 bytes, then a segment can be located
at 0x10000040 - 0x1000043f, and a segment from another ring at 0x10000440 -
0x1000083f. The last trb in the first segment at 0x10000430 will then translate
to the same radix tree key as the first trb of the second segment, while they
are in different rings!
This patches fixes this by changing the alignment of the dma pool to be 1KB
rather then 64 bytes. An alternative fix would be to reduce the shift used
to calculate the radix tree keys, but that would (slighlty) grow the radix
trees so I believe this is the better fix.
Note this patch is mostly theoretical since in practice I've not seen
the dma_pool actually return not 1KB aligned memory.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 60fc6720007f..c089668308ad 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -158,7 +158,7 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, * * The radix tree maps the upper portion of the TRB DMA address to a ring * segment that has the same upper portion of DMA addresses. For example, say I - * have segments of size 1KB, that are always 64-byte aligned. A segment may + * have segments of size 1KB, that are always 1KB aligned. A segment may * start at 0x10c91000 and end at 0x10c913f0. If I use the upper 10 bits, the * key to the stream ID is 0x43244. I can use the DMA address of the TRB to * pass the radix tree a key to get the right stream ID: @@ -2375,11 +2375,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) /* * Initialize the ring segment pool. The ring must be a contiguous * structure comprised of TRBs. The TRBs must be 16 byte aligned, - * however, the command ring segment needs 64-byte aligned segments, - * so we pick the greater alignment need. + * however, the command ring segment needs 64-byte aligned segments + * and our use of dma addresses in the trb_address_map radix tree needs + * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. */ xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, - TRB_SEGMENT_SIZE, 64, xhci->page_size); + TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); /* See Table 46 and Note on Figure 55 */ xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, |