master
h 119 lines 3.39 KB
Raw
1 /*
2 * vhost-vdpa.h
3 *
4 * Copyright(c) 2017-2018 Intel Corporation.
5 * Copyright(c) 2020 Red Hat, Inc.
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
9 *
10 */
11
12 #ifndef HW_VIRTIO_VHOST_VDPA_H
13 #define HW_VIRTIO_VHOST_VDPA_H
14
15 #include <gmodule.h>
16
17 #include "hw/virtio/vhost-iova-tree.h"
18 #include "hw/virtio/vhost-shadow-virtqueue.h"
19 #include "hw/virtio/virtio.h"
20 #include "standard-headers/linux/vhost_types.h"
21
22 /*
23 * ASID dedicated to map guest's addresses. If SVQ is disabled it maps GPA to
24 * qemu's IOVA. If SVQ is enabled it maps also the SVQ vring here
25 */
26 #define VHOST_VDPA_GUEST_PA_ASID 0
27
28 typedef struct VhostVDPAHostNotifier {
29 MemoryRegion mr;
30 void *addr;
31 } VhostVDPAHostNotifier;
32
33 typedef enum SVQTransitionState {
34 SVQ_TSTATE_DISABLING = -1,
35 SVQ_TSTATE_DONE,
36 SVQ_TSTATE_ENABLING
37 } SVQTransitionState;
38
39 /* Info shared by all vhost_vdpa device models */
40 typedef struct vhost_vdpa_shared {
41 int device_fd;
42 MemoryListener listener;
43 struct vhost_vdpa_iova_range iova_range;
44 QLIST_HEAD(, vdpa_iommu) iommu_list;
45
46 /*
47 * IOVA mapping used by the Shadow Virtqueue
48 *
49 * It is shared among all ASID for simplicity, whether CVQ shares ASID with
50 * guest or not:
51 * - Memory listener need access to guest's memory addresses allocated in
52 * the IOVA tree.
53 * - There should be plenty of IOVA address space for both ASID not to
54 * worry about collisions between them. Guest's translations are still
55 * validated with virtio virtqueue_pop so there is no risk for the guest
56 * to access memory that it shouldn't.
57 *
58 * To allocate a iova tree per ASID is doable but it complicates the code
59 * and it is not worth it for the moment.
60 */
61 VhostIOVATree *iova_tree;
62
63 /* Copy of backend features */
64 uint64_t backend_cap;
65
66 bool iotlb_batch_begin_sent;
67
68 /*
69 * The memory listener has been registered, so DMA maps have been sent to
70 * the device.
71 */
72 bool listener_registered;
73
74 /* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */
75 bool shadow_data;
76
77 /* SVQ switching is in progress, or already completed? */
78 SVQTransitionState svq_switching;
79
80 /*
81 * Device suspended successfully.
82 * The vhost_vdpa devices cannot have different suspended states.
83 */
84 bool suspended;
85 } VhostVDPAShared;
86
87 typedef struct vhost_vdpa {
88 int index;
89 uint32_t address_space_id;
90 uint64_t acked_features;
91 bool shadow_vqs_enabled;
92 VhostVDPAShared *shared;
93 GPtrArray *shadow_vqs;
94 const VhostShadowVirtqueueOps *shadow_vq_ops;
95 void *shadow_vq_ops_opaque;
96 struct vhost_dev *dev;
97 Error *migration_blocker;
98 VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
99 IOMMUNotifier n;
100 } VhostVDPA;
101
102 int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range);
103 int vhost_vdpa_set_vring_ready(struct vhost_vdpa *v, unsigned idx);
104
105 int vhost_vdpa_dma_map(VhostVDPAShared *s, uint32_t asid, hwaddr iova,
106 hwaddr size, void *vaddr, bool readonly);
107 int vhost_vdpa_dma_unmap(VhostVDPAShared *s, uint32_t asid, hwaddr iova,
108 hwaddr size);
109
110 typedef struct vdpa_iommu {
111 VhostVDPAShared *dev_shared;
112 IOMMUMemoryRegion *iommu_mr;
113 hwaddr iommu_offset;
114 IOMMUNotifier n;
115 QLIST_ENTRY(vdpa_iommu) iommu_next;
116 } VDPAIOMMUState;
117
118
119 #endif