From: Chuck Lever <chuck.lever@xxxxxxxxxx> Cc: Alexander Potapenko <glider@xxxxxxxxxx> Cc: kasan-dev@xxxxxxxxxxxxxxxx Cc: linux-mm@xxxxxxxxx Cc: iommu@xxxxxxxxxxxxxxx Cc: linux-rdma@xxxxxxxxxxxxxxx Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> --- include/linux/kmsan.h | 20 ++++++++++++++++++++ mm/kmsan/hooks.c | 13 +++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h index e0c23a32cdf0..36c581a18b30 100644 --- a/include/linux/kmsan.h +++ b/include/linux/kmsan.h @@ -18,6 +18,7 @@ struct page; struct kmem_cache; struct task_struct; struct scatterlist; +struct bio_vec; struct urb; #ifdef CONFIG_KMSAN @@ -209,6 +210,20 @@ void kmsan_handle_dma(struct page *page, size_t offset, size_t size, void kmsan_handle_dma_sg(struct scatterlist *sg, int nents, enum dma_data_direction dir); +/** + * kmsan_handle_dma_bvecs() - Handle a DMA transfer using bio_vec array. + * @bvecs: bio_vec array holding DMA buffers. + * @nents: number of scatterlist entries. + * @dir: one of possible dma_data_direction values. + * + * Depending on @direction, KMSAN: + * * checks the buffers in the bio_vec array, if they are copied to device; + * * initializes the buffers, if they are copied from device; + * * does both, if this is a DMA_BIDIRECTIONAL transfer. + */ +void kmsan_handle_dma_bvecs(struct bio_vec *bv, int nents, + enum dma_data_direction dir); + /** * kmsan_handle_urb() - Handle a USB data transfer. * @urb: struct urb pointer. @@ -321,6 +336,11 @@ static inline void kmsan_handle_dma_sg(struct scatterlist *sg, int nents, { } +static inline void kmsan_handle_dma_bvecs(struct bio_vec *bv, int nents, + enum dma_data_direction dir) +{ +} + static inline void kmsan_handle_urb(const struct urb *urb, bool is_out) { } diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c index 5d6e2dee5692..87846011c9bd 100644 --- a/mm/kmsan/hooks.c +++ b/mm/kmsan/hooks.c @@ -358,6 +358,19 @@ void kmsan_handle_dma_sg(struct scatterlist *sg, int nents, dir); } +void kmsan_handle_dma_bvecs(struct bio_vec *bvecs, int nents, + enum dma_data_direction dir) +{ + struct bio_vec *item; + int i; + + for (i = 0; i < nents; i++) { + item = &bvecs[i]; + kmsan_handle_dma(bv_page(item), item->bv_offset, item->bv_len, + dir); + } +} + /* Functions from kmsan-checks.h follow. */ void kmsan_poison_memory(const void *address, size_t size, gfp_t flags) {