xref: /linux/drivers/vdpa/vdpa_user/iova_domain.h (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
18c773d53SXie Yongji /* SPDX-License-Identifier: GPL-2.0-only */
28c773d53SXie Yongji /*
38c773d53SXie Yongji  * MMU-based software IOTLB.
48c773d53SXie Yongji  *
58c773d53SXie Yongji  * Copyright (C) 2020-2021 Bytedance Inc. and/or its affiliates. All rights reserved.
68c773d53SXie Yongji  *
78c773d53SXie Yongji  * Author: Xie Yongji <xieyongji@bytedance.com>
88c773d53SXie Yongji  *
98c773d53SXie Yongji  */
108c773d53SXie Yongji 
118c773d53SXie Yongji #ifndef _VDUSE_IOVA_DOMAIN_H
128c773d53SXie Yongji #define _VDUSE_IOVA_DOMAIN_H
138c773d53SXie Yongji 
148c773d53SXie Yongji #include <linux/iova.h>
158c773d53SXie Yongji #include <linux/dma-mapping.h>
168c773d53SXie Yongji #include <linux/vhost_iotlb.h>
178c773d53SXie Yongji 
188c773d53SXie Yongji #define IOVA_START_PFN 1
198c773d53SXie Yongji 
208c773d53SXie Yongji #define INVALID_PHYS_ADDR (~(phys_addr_t)0)
218c773d53SXie Yongji 
228c773d53SXie Yongji struct vduse_bounce_map {
238c773d53SXie Yongji 	struct page *bounce_page;
24*955abe0aSJason Wang 	struct page *user_bounce_page;
258c773d53SXie Yongji 	u64 orig_phys;
268c773d53SXie Yongji };
278c773d53SXie Yongji 
288c773d53SXie Yongji struct vduse_iova_domain {
298c773d53SXie Yongji 	struct iova_domain stream_iovad;
308c773d53SXie Yongji 	struct iova_domain consistent_iovad;
318c773d53SXie Yongji 	struct vduse_bounce_map *bounce_maps;
328c773d53SXie Yongji 	size_t bounce_size;
338c773d53SXie Yongji 	unsigned long iova_limit;
348c773d53SXie Yongji 	int bounce_map;
358c773d53SXie Yongji 	struct vhost_iotlb *iotlb;
368c773d53SXie Yongji 	spinlock_t iotlb_lock;
378c773d53SXie Yongji 	struct file *file;
386c77ed22SXie Yongji 	bool user_bounce_pages;
396c77ed22SXie Yongji 	rwlock_t bounce_lock;
408c773d53SXie Yongji };
418c773d53SXie Yongji 
428c773d53SXie Yongji int vduse_domain_set_map(struct vduse_iova_domain *domain,
438c773d53SXie Yongji 			 struct vhost_iotlb *iotlb);
448c773d53SXie Yongji 
458c773d53SXie Yongji void vduse_domain_clear_map(struct vduse_iova_domain *domain,
468c773d53SXie Yongji 			    struct vhost_iotlb *iotlb);
478c773d53SXie Yongji 
48d7b4e328SMaxime Coquelin void vduse_domain_sync_single_for_device(struct vduse_iova_domain *domain,
49d7b4e328SMaxime Coquelin 				      dma_addr_t dma_addr, size_t size,
50d7b4e328SMaxime Coquelin 				      enum dma_data_direction dir);
51d7b4e328SMaxime Coquelin 
52d7b4e328SMaxime Coquelin void vduse_domain_sync_single_for_cpu(struct vduse_iova_domain *domain,
53d7b4e328SMaxime Coquelin 				      dma_addr_t dma_addr, size_t size,
54d7b4e328SMaxime Coquelin 				      enum dma_data_direction dir);
55d7b4e328SMaxime Coquelin 
568c773d53SXie Yongji dma_addr_t vduse_domain_map_page(struct vduse_iova_domain *domain,
578c773d53SXie Yongji 				 struct page *page, unsigned long offset,
588c773d53SXie Yongji 				 size_t size, enum dma_data_direction dir,
598c773d53SXie Yongji 				 unsigned long attrs);
608c773d53SXie Yongji 
618c773d53SXie Yongji void vduse_domain_unmap_page(struct vduse_iova_domain *domain,
628c773d53SXie Yongji 			     dma_addr_t dma_addr, size_t size,
638c773d53SXie Yongji 			     enum dma_data_direction dir, unsigned long attrs);
648c773d53SXie Yongji 
658c773d53SXie Yongji void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
668c773d53SXie Yongji 				  size_t size, dma_addr_t *dma_addr,
678c773d53SXie Yongji 				  gfp_t flag, unsigned long attrs);
688c773d53SXie Yongji 
698c773d53SXie Yongji void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size,
708c773d53SXie Yongji 				void *vaddr, dma_addr_t dma_addr,
718c773d53SXie Yongji 				unsigned long attrs);
728c773d53SXie Yongji 
738c773d53SXie Yongji void vduse_domain_reset_bounce_map(struct vduse_iova_domain *domain);
748c773d53SXie Yongji 
756c77ed22SXie Yongji int vduse_domain_add_user_bounce_pages(struct vduse_iova_domain *domain,
766c77ed22SXie Yongji 				       struct page **pages, int count);
776c77ed22SXie Yongji 
786c77ed22SXie Yongji void vduse_domain_remove_user_bounce_pages(struct vduse_iova_domain *domain);
796c77ed22SXie Yongji 
808c773d53SXie Yongji void vduse_domain_destroy(struct vduse_iova_domain *domain);
818c773d53SXie Yongji 
828c773d53SXie Yongji struct vduse_iova_domain *vduse_domain_create(unsigned long iova_limit,
838c773d53SXie Yongji 					      size_t bounce_size);
848c773d53SXie Yongji 
858c773d53SXie Yongji int vduse_domain_init(void);
868c773d53SXie Yongji 
878c773d53SXie Yongji void vduse_domain_exit(void);
888c773d53SXie Yongji 
898c773d53SXie Yongji #endif /* _VDUSE_IOVA_DOMAIN_H */
90