linux-stable/include
Linus Torvalds 890f78e54b Revert "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
commit bddac7c1e0 upstream.

This reverts commit aa6f8dcbab.

It turns out this breaks at least the ath9k wireless driver, and
possibly others.

What the ath9k driver does on packet receive is to set up the DMA
transfer with:

  int ath_rx_init(..)
  ..
                bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
                                                 common->rx_bufsize,
                                                 DMA_FROM_DEVICE);

and then the receive logic (through ath_rx_tasklet()) will fetch
incoming packets

  static bool ath_edma_get_buffers(..)
  ..
        dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
                                common->rx_bufsize, DMA_FROM_DEVICE);

        ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data);
        if (ret == -EINPROGRESS) {
                /*let device gain the buffer again*/
                dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
                                common->rx_bufsize, DMA_FROM_DEVICE);
                return false;
        }

and it's worth noting how that first DMA sync:

    dma_sync_single_for_cpu(..DMA_FROM_DEVICE);

is there to make sure the CPU can read the DMA buffer (possibly by
copying it from the bounce buffer area, or by doing some cache flush).
The iommu correctly turns that into a "copy from bounce bufer" so that
the driver can look at the state of the packets.

In the meantime, the device may continue to write to the DMA buffer, but
we at least have a snapshot of the state due to that first DMA sync.

But that _second_ DMA sync:

    dma_sync_single_for_device(..DMA_FROM_DEVICE);

is telling the DMA mapping that the CPU wasn't interested in the area
because the packet wasn't there.  In the case of a DMA bounce buffer,
that is a no-op.

Note how it's not a sync for the CPU (the "for_device()" part), and it's
not a sync for data written by the CPU (the "DMA_FROM_DEVICE" part).

Or rather, it _should_ be a no-op.  That's what commit aa6f8dcbab
broke: it made the code bounce the buffer unconditionally, and changed
the DMA_FROM_DEVICE to just unconditionally and illogically be
DMA_TO_DEVICE.

[ Side note: purely within the confines of the swiotlb driver it wasn't
  entirely illogical: The reason it did that odd DMA_FROM_DEVICE ->
  DMA_TO_DEVICE conversion thing is because inside the swiotlb driver,
  it uses just a swiotlb_bounce() helper that doesn't care about the
  whole distinction of who the sync is for - only which direction to
  bounce.

  So it took the "sync for device" to mean that the CPU must have been
  the one writing, and thought it meant DMA_TO_DEVICE. ]

Also note how the commentary in that commit was wrong, probably due to
that whole confusion, claiming that the commit makes the swiotlb code

                                  "bounce unconditionally (that is, also
    when dir == DMA_TO_DEVICE) in order do avoid synchronising back stale
    data from the swiotlb buffer"

which is nonsensical for two reasons:

 - that "also when dir == DMA_TO_DEVICE" is nonsensical, as that was
   exactly when it always did - and should do - the bounce.

 - since this is a sync for the device (not for the CPU), we're clearly
   fundamentally not coping back stale data from the bounce buffers at
   all, because we'd be copying *to* the bounce buffers.

So that commit was just very confused.  It confused the direction of the
synchronization (to the device, not the cpu) with the direction of the
DMA (from the device).

Reported-and-bisected-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Reported-by: Olha Cherevyk <olha.cherevyk@gmail.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Kalle Valo <kvalo@kernel.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Toke Høiland-Jørgensen <toke@toke.dk>
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-04-08 14:22:45 +02:00
..
acpi ACPICA: actypes.h: Expand the ACPI_ACCESS_ definitions 2022-01-27 11:04:49 +01:00
asm-generic bitops: protect find_first_{,zero}_bit properly 2022-01-27 11:05:34 +01:00
clocksource
crypto
drm drm/ttm: remove ttm_bo_vm_insert_huge() 2021-11-18 19:17:08 +01:00
dt-bindings
keys
kunit kunit: fix kernel-doc warnings due to mismatched arg names 2021-10-06 17:54:07 -06:00
kvm
linux Revert "swiotlb: rework "fix info leak with DMA_FROM_DEVICE"" 2022-04-08 14:22:45 +02:00
math-emu
media media: cec: fix a deadlock situation 2022-01-27 11:02:53 +01:00
memory memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode 2021-11-18 19:16:01 +01:00
misc
net vsock: each transport cycles only on its own sockets 2022-03-23 09:16:41 +01:00
pcmcia
ras
rdma RDMA/netlink: Add __maybe_unused to static inline in C file 2021-11-25 09:49:07 +01:00
scsi scsi: core: Avoid leaving shost->last_reset with stale value if EH does not run 2021-11-18 19:15:51 +01:00
soc net: dsa: tag_ocelot_8021q: break circular dependency with ocelot switch lib 2021-10-12 17:35:18 -07:00
sound ALSA: pcm: Fix races among concurrent hw_params and hw_free calls 2022-03-28 09:58:43 +02:00
target scsi: target: Fix ordered tag handling 2021-11-25 09:48:29 +01:00
trace SUNRPC: Fix sockaddr handling in svcsock_accept_class trace points 2022-03-08 19:12:37 +01:00
uapi HID: add mapping for KEY_ALL_APPLICATIONS 2022-03-08 19:12:53 +01:00
vdso
video
xen xen/gnttab: fix gnttab_end_foreign_access() without page specified 2022-03-11 12:22:37 +01:00