162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * MMU-based software IOTLB.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2020-2021 Bytedance Inc. and/or its affiliates. All rights reserved.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Author: Xie Yongji <xieyongji@bytedance.com>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef _VDUSE_IOVA_DOMAIN_H
1262306a36Sopenharmony_ci#define _VDUSE_IOVA_DOMAIN_H
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/iova.h>
1562306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1662306a36Sopenharmony_ci#include <linux/vhost_iotlb.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define IOVA_START_PFN 1
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define INVALID_PHYS_ADDR (~(phys_addr_t)0)
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistruct vduse_bounce_map {
2362306a36Sopenharmony_ci	struct page *bounce_page;
2462306a36Sopenharmony_ci	u64 orig_phys;
2562306a36Sopenharmony_ci};
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistruct vduse_iova_domain {
2862306a36Sopenharmony_ci	struct iova_domain stream_iovad;
2962306a36Sopenharmony_ci	struct iova_domain consistent_iovad;
3062306a36Sopenharmony_ci	struct vduse_bounce_map *bounce_maps;
3162306a36Sopenharmony_ci	size_t bounce_size;
3262306a36Sopenharmony_ci	unsigned long iova_limit;
3362306a36Sopenharmony_ci	int bounce_map;
3462306a36Sopenharmony_ci	struct vhost_iotlb *iotlb;
3562306a36Sopenharmony_ci	spinlock_t iotlb_lock;
3662306a36Sopenharmony_ci	struct file *file;
3762306a36Sopenharmony_ci	bool user_bounce_pages;
3862306a36Sopenharmony_ci	rwlock_t bounce_lock;
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciint vduse_domain_set_map(struct vduse_iova_domain *domain,
4262306a36Sopenharmony_ci			 struct vhost_iotlb *iotlb);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_civoid vduse_domain_clear_map(struct vduse_iova_domain *domain,
4562306a36Sopenharmony_ci			    struct vhost_iotlb *iotlb);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cidma_addr_t vduse_domain_map_page(struct vduse_iova_domain *domain,
4862306a36Sopenharmony_ci				 struct page *page, unsigned long offset,
4962306a36Sopenharmony_ci				 size_t size, enum dma_data_direction dir,
5062306a36Sopenharmony_ci				 unsigned long attrs);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_civoid vduse_domain_unmap_page(struct vduse_iova_domain *domain,
5362306a36Sopenharmony_ci			     dma_addr_t dma_addr, size_t size,
5462306a36Sopenharmony_ci			     enum dma_data_direction dir, unsigned long attrs);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_civoid *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
5762306a36Sopenharmony_ci				  size_t size, dma_addr_t *dma_addr,
5862306a36Sopenharmony_ci				  gfp_t flag, unsigned long attrs);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_civoid vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size,
6162306a36Sopenharmony_ci				void *vaddr, dma_addr_t dma_addr,
6262306a36Sopenharmony_ci				unsigned long attrs);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_civoid vduse_domain_reset_bounce_map(struct vduse_iova_domain *domain);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciint vduse_domain_add_user_bounce_pages(struct vduse_iova_domain *domain,
6762306a36Sopenharmony_ci				       struct page **pages, int count);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_civoid vduse_domain_remove_user_bounce_pages(struct vduse_iova_domain *domain);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_civoid vduse_domain_destroy(struct vduse_iova_domain *domain);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistruct vduse_iova_domain *vduse_domain_create(unsigned long iova_limit,
7462306a36Sopenharmony_ci					      size_t bounce_size);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciint vduse_domain_init(void);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_civoid vduse_domain_exit(void);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#endif /* _VDUSE_IOVA_DOMAIN_H */
81