On 2020-08-26 18:02, Kalle Valo wrote:
Christian Lamparter <chunkeey@xxxxxxxxx> writes:
On 2020-08-02 15:29, Jia-Ju Bai wrote:
In p54p_tx(), skb->data is mapped to streaming DMA on line 337:
mapping = pci_map_single(..., skb->data, ...);
Then skb->data is accessed on line 349:
desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
This access may cause data inconsistency between CPU cache and hardware.
To fix this problem, ((struct p54_hdr *)skb->data)->req_id is stored in
a local variable before DMA mapping, and then the driver accesses this
local variable instead of skb->data.
Interesting. Please bear with me here. From my understanding, the
streaming direction is set to PCI_DMA_TODEVICE. So is it really
possible for the hardware to interfere with the data without the IOMMU
catching this?
Also is there any documentation about this scenario? I would like to
understand this better.
I usually rely on the information present in Documentation:
<https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt>
The relevant extract for p54's DMA_TO_DEVICE decision likely comes from:
"For Networking drivers, it's a rather simple affair. For transmit
packets, map/unmap them with the DMA_TO_DEVICE direction
specifier. For receive packets, just the opposite, map/unmap them
with the DMA_FROM_DEVICE direction specifier."
"Only streaming mappings specify a direction, consistent mappings
implicitly have a direction attribute setting of DMA_BIDIRECTIONAL."
But looking around on the Internet, I came across this in "Chapter 15.
Memory Mapping and DMA" of the Linux Device Drivers, 3rd Edition:
<https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch15.html>
|Setting up streaming DMA mappings
|[...]
|
|Some important rules apply to streaming DMA mappings:
| * [...]
|
| * Once a buffer has been mapped, it belongs to the device, not the
| processor. Until the buffer has been unmapped, the driver should not
| touch its contents in any way. Only after dma_unmap_single has been
| called is it safe for the driver to access the contents of the
| buffer (with one exception that we see shortly). Among other things,
| this rule implies that a buffer being written to a device cannot be
| mapped until it contains all the data to write."
|
| [...] (More informative text, but only)
From the sentence "Once a buffer has been mapped, it belongs to the
device, not the processor". I think that Jia-Ju Bai's patch is doing
exactly this "by the book". Therefore, it should be applied and
backported:
Cc: <stable@xxxxxxxxxxxxxxx>
Acked-by: Christian Lamparter <chunkeey@xxxxxxxxx>
Cheers,
Christian