xref: /openbmc/linux/drivers/vdpa/vdpa_user/iova_domain.h (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
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;
248c773d53SXie Yongji 	u64 orig_phys;
258c773d53SXie Yongji };
268c773d53SXie Yongji 
278c773d53SXie Yongji struct vduse_iova_domain {
288c773d53SXie Yongji 	struct iova_domain stream_iovad;
298c773d53SXie Yongji 	struct iova_domain consistent_iovad;
308c773d53SXie Yongji 	struct vduse_bounce_map *bounce_maps;
318c773d53SXie Yongji 	size_t bounce_size;
328c773d53SXie Yongji 	unsigned long iova_limit;
338c773d53SXie Yongji 	int bounce_map;
348c773d53SXie Yongji 	struct vhost_iotlb *iotlb;
358c773d53SXie Yongji 	spinlock_t iotlb_lock;
368c773d53SXie Yongji 	struct file *file;
37*6c77ed22SXie Yongji 	bool user_bounce_pages;
38*6c77ed22SXie Yongji 	rwlock_t bounce_lock;
398c773d53SXie Yongji };
408c773d53SXie Yongji 
418c773d53SXie Yongji int vduse_domain_set_map(struct vduse_iova_domain *domain,
428c773d53SXie Yongji 			 struct vhost_iotlb *iotlb);
438c773d53SXie Yongji 
448c773d53SXie Yongji void vduse_domain_clear_map(struct vduse_iova_domain *domain,
458c773d53SXie Yongji 			    struct vhost_iotlb *iotlb);
468c773d53SXie Yongji 
478c773d53SXie Yongji dma_addr_t vduse_domain_map_page(struct vduse_iova_domain *domain,
488c773d53SXie Yongji 				 struct page *page, unsigned long offset,
498c773d53SXie Yongji 				 size_t size, enum dma_data_direction dir,
508c773d53SXie Yongji 				 unsigned long attrs);
518c773d53SXie Yongji 
528c773d53SXie Yongji void vduse_domain_unmap_page(struct vduse_iova_domain *domain,
538c773d53SXie Yongji 			     dma_addr_t dma_addr, size_t size,
548c773d53SXie Yongji 			     enum dma_data_direction dir, unsigned long attrs);
558c773d53SXie Yongji 
568c773d53SXie Yongji void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
578c773d53SXie Yongji 				  size_t size, dma_addr_t *dma_addr,
588c773d53SXie Yongji 				  gfp_t flag, unsigned long attrs);
598c773d53SXie Yongji 
608c773d53SXie Yongji void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size,
618c773d53SXie Yongji 				void *vaddr, dma_addr_t dma_addr,
628c773d53SXie Yongji 				unsigned long attrs);
638c773d53SXie Yongji 
648c773d53SXie Yongji void vduse_domain_reset_bounce_map(struct vduse_iova_domain *domain);
658c773d53SXie Yongji 
66*6c77ed22SXie Yongji int vduse_domain_add_user_bounce_pages(struct vduse_iova_domain *domain,
67*6c77ed22SXie Yongji 				       struct page **pages, int count);
68*6c77ed22SXie Yongji 
69*6c77ed22SXie Yongji void vduse_domain_remove_user_bounce_pages(struct vduse_iova_domain *domain);
70*6c77ed22SXie Yongji 
718c773d53SXie Yongji void vduse_domain_destroy(struct vduse_iova_domain *domain);
728c773d53SXie Yongji 
738c773d53SXie Yongji struct vduse_iova_domain *vduse_domain_create(unsigned long iova_limit,
748c773d53SXie Yongji 					      size_t bounce_size);
758c773d53SXie Yongji 
768c773d53SXie Yongji int vduse_domain_init(void);
778c773d53SXie Yongji 
788c773d53SXie Yongji void vduse_domain_exit(void);
798c773d53SXie Yongji 
808c773d53SXie Yongji #endif /* _VDUSE_IOVA_DOMAIN_H */
81