/* SPDX-License-Identifier: GPL-2.0-only */ /* * MMU-based software IOTLB. * * Copyright (C) 2020-2021 Bytedance Inc. and/or its affiliates. All rights reserved. * * Author: Xie Yongji * */ #ifndef _VDUSE_IOVA_DOMAIN_H #define _VDUSE_IOVA_DOMAIN_H #include #include #include #define IOVA_START_PFN 1 #define INVALID_PHYS_ADDR (~(phys_addr_t)0) struct vduse_bounce_map { struct page *bounce_page; struct page *user_bounce_page; u64 orig_phys; }; struct vduse_iova_domain { struct iova_domain stream_iovad; struct iova_domain consistent_iovad; struct vduse_bounce_map *bounce_maps; size_t bounce_size; unsigned long iova_limit; int bounce_map; struct vhost_iotlb *iotlb; spinlock_t iotlb_lock; struct file *file; bool user_bounce_pages; rwlock_t bounce_lock; }; int vduse_domain_set_map(struct vduse_iova_domain *domain, struct vhost_iotlb *iotlb); void vduse_domain_clear_map(struct vduse_iova_domain *domain, struct vhost_iotlb *iotlb); void vduse_domain_sync_single_for_device(struct vduse_iova_domain *domain, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir); void vduse_domain_sync_single_for_cpu(struct vduse_iova_domain *domain, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir); dma_addr_t vduse_domain_map_page(struct vduse_iova_domain *domain, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, unsigned long attrs); void vduse_domain_unmap_page(struct vduse_iova_domain *domain, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir, unsigned long attrs); void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, size_t size, dma_addr_t *dma_addr, gfp_t flag, unsigned long attrs); void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size, void *vaddr, dma_addr_t dma_addr, unsigned long attrs); void vduse_domain_reset_bounce_map(struct vduse_iova_domain *domain); int vduse_domain_add_user_bounce_pages(struct vduse_iova_domain *domain, struct page **pages, int count); void vduse_domain_remove_user_bounce_pages(struct vduse_iova_domain *domain); void vduse_domain_destroy(struct vduse_iova_domain *domain); struct vduse_iova_domain *vduse_domain_create(unsigned long iova_limit, size_t bounce_size); int vduse_domain_init(void); void vduse_domain_exit(void); #endif /* _VDUSE_IOVA_DOMAIN_H */