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