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