virtio_input: fix DMA cacheline alignment for evts
Subsystems (10)
A message that is not in the archive (sent off-list or not yet received): [email protected]
Michael S. Tsirkin
maintainerRFC PATCH 9/13 virtio_input: fix DMA cacheline alignment for evts
On non-cache-coherent platforms, when a structure contains a buffer used for DMA alongside fields that the CPU writes to, cacheline sharing can cause data corruption.
The evts array is used for DMA_FROM_DEVICE operations via virtqueue_add_inbuf(). The adjacent lock and ready fields are written by the CPU during normal operation. If these share cachelines with evts, CPU writes can corrupt DMA data.
Add __dma_from_device_aligned_begin/end annotations to ensure evts is isolated in its own cachelines.
--- drivers/virtio/virtio_input.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/virtio/virtio_input.c +3 -0
@@ -4,6 +4,7 @@#include <linux/virtio_config.h> #include <linux/input.h> #include <linux/slab.h> +#include <linux/dma-mapping.h> #include <uapi/linux/virtio_ids.h> #include <uapi/linux/virtio_input.h>
@@ -16,7 +17,9 @@ struct virtio_input {char serial[64 ];char phys[64 ];struct virtqueue *evt, *sts; +__dma_from_device_aligned_begin struct virtio_input_event evts[64]; +__dma_from_device_aligned_end spinlock_t lock;bool ready; };
Signature · 1 line
MST
Michael S. Tsirkin
maintainerRFC PATCH 11/13 virtio-rng: fix DMA cacheline alignment for data buffer
In reply to a message not in the archiveAdd __dma_from_device_aligned_begin annotation before the data buffer in struct virtrng_info to ensure proper cacheline alignment on non-cache-coherent platforms.
The data buffer is used for DMA_FROM_DEVICE via virtqueue_add_inbuf() and is adjacent to CPU-written fields (data_avail, data_idx). Without proper alignment, the device writing to the DMA buffer and the CPU writing to adjacent fields could corrupt each other's data on platforms where DMA cache maintenance is at cacheline granularity.
--- drivers/char/hw_random/virtio-rng.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/char/hw_random/virtio-rng.c +2 -0
@@ -11,6 +11,7 @@#include <linux/spinlock.h> #include <linux/virtio.h> #include <linux/virtio_rng.h> +#include <linux/dma-mapping.h> #include <linux/module.h> #include <linux/slab.h>
@@ -28,6 +29,7 @@ struct virtrng_info {unsigned int data_avail;unsigned int data_idx;/* minimal size returned by rng_buffer_size() */ + __dma_from_device_aligned_begin#if SMP_CACHE_BYTES <32 u8 data[32 ];#else
Signature · 1 line
MST