1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * MMU-based software IOTLB. |
4 | * |
5 | * Copyright (C) 2020-2021 Bytedance Inc. and/or its affiliates. All rights reserved. |
6 | * |
7 | * Author: Xie Yongji <xieyongji@bytedance.com> |
8 | * |
9 | */ |
10 | |
11 | #ifndef _VDUSE_IOVA_DOMAIN_H |
12 | #define _VDUSE_IOVA_DOMAIN_H |
13 | |
14 | #include <linux/iova.h> |
15 | #include <linux/dma-mapping.h> |
16 | #include <linux/vhost_iotlb.h> |
17 | |
18 | #define IOVA_START_PFN 1 |
19 | |
20 | #define INVALID_PHYS_ADDR (~(phys_addr_t)0) |
21 | |
22 | struct vduse_bounce_map { |
23 | struct page *bounce_page; |
24 | u64 orig_phys; |
25 | }; |
26 | |
27 | struct vduse_iova_domain { |
28 | struct iova_domain stream_iovad; |
29 | struct iova_domain consistent_iovad; |
30 | struct vduse_bounce_map *bounce_maps; |
31 | size_t bounce_size; |
32 | unsigned long iova_limit; |
33 | int bounce_map; |
34 | struct vhost_iotlb *iotlb; |
35 | spinlock_t iotlb_lock; |
36 | struct file *file; |
37 | bool user_bounce_pages; |
38 | rwlock_t bounce_lock; |
39 | }; |
40 | |
41 | int vduse_domain_set_map(struct vduse_iova_domain *domain, |
42 | struct vhost_iotlb *iotlb); |
43 | |
44 | void vduse_domain_clear_map(struct vduse_iova_domain *domain, |
45 | struct vhost_iotlb *iotlb); |
46 | |
47 | void vduse_domain_sync_single_for_device(struct vduse_iova_domain *domain, |
48 | dma_addr_t dma_addr, size_t size, |
49 | enum dma_data_direction dir); |
50 | |
51 | void vduse_domain_sync_single_for_cpu(struct vduse_iova_domain *domain, |
52 | dma_addr_t dma_addr, size_t size, |
53 | enum dma_data_direction dir); |
54 | |
55 | dma_addr_t vduse_domain_map_page(struct vduse_iova_domain *domain, |
56 | struct page *page, unsigned long offset, |
57 | size_t size, enum dma_data_direction dir, |
58 | unsigned long attrs); |
59 | |
60 | void vduse_domain_unmap_page(struct vduse_iova_domain *domain, |
61 | dma_addr_t dma_addr, size_t size, |
62 | enum dma_data_direction dir, unsigned long attrs); |
63 | |
64 | void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, |
65 | size_t size, dma_addr_t *dma_addr, |
66 | gfp_t flag, unsigned long attrs); |
67 | |
68 | void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size, |
69 | void *vaddr, dma_addr_t dma_addr, |
70 | unsigned long attrs); |
71 | |
72 | void vduse_domain_reset_bounce_map(struct vduse_iova_domain *domain); |
73 | |
74 | int vduse_domain_add_user_bounce_pages(struct vduse_iova_domain *domain, |
75 | struct page **pages, int count); |
76 | |
77 | void vduse_domain_remove_user_bounce_pages(struct vduse_iova_domain *domain); |
78 | |
79 | void vduse_domain_destroy(struct vduse_iova_domain *domain); |
80 | |
81 | struct vduse_iova_domain *vduse_domain_create(unsigned long iova_limit, |
82 | size_t bounce_size); |
83 | |
84 | int vduse_domain_init(void); |
85 | |
86 | void vduse_domain_exit(void); |
87 | |
88 | #endif /* _VDUSE_IOVA_DOMAIN_H */ |
89 | |