1 #include "kvm/devices.h"
2 #include "kvm/virtio-mmio.h"
3 #include "kvm/ioeventfd.h"
4 #include "kvm/virtio.h"
5 #include "kvm/kvm.h"
6 #include "kvm/irq.h"
7 #include "kvm/fdt.h"
8
9 #include <linux/virtio_mmio.h>
10 #include <string.h>
11
12 static u32 virtio_mmio_io_space_blocks = KVM_VIRTIO_MMIO_AREA;
13
virtio_mmio_get_io_space_block(u32 size)14 static u32 virtio_mmio_get_io_space_block(u32 size)
15 {
16 u32 block = virtio_mmio_io_space_blocks;
17 virtio_mmio_io_space_blocks += size;
18
19 return block;
20 }
21
virtio_mmio_ioevent_callback(struct kvm * kvm,void * param)22 static void virtio_mmio_ioevent_callback(struct kvm *kvm, void *param)
23 {
24 struct virtio_mmio_ioevent_param *ioeventfd = param;
25 struct virtio_mmio *vmmio = ioeventfd->vdev->virtio;
26
27 ioeventfd->vdev->ops->notify_vq(kvm, vmmio->dev, ioeventfd->vq);
28 }
29
virtio_mmio_init_ioeventfd(struct kvm * kvm,struct virtio_device * vdev,u32 vq)30 int virtio_mmio_init_ioeventfd(struct kvm *kvm, struct virtio_device *vdev,
31 u32 vq)
32 {
33 struct virtio_mmio *vmmio = vdev->virtio;
34 struct ioevent ioevent;
35 int err;
36
37 vmmio->ioeventfds[vq] = (struct virtio_mmio_ioevent_param) {
38 .vdev = vdev,
39 .vq = vq,
40 };
41
42 ioevent = (struct ioevent) {
43 .io_addr = vmmio->addr + VIRTIO_MMIO_QUEUE_NOTIFY,
44 .io_len = sizeof(u32),
45 .fn = virtio_mmio_ioevent_callback,
46 .fn_ptr = &vmmio->ioeventfds[vq],
47 .datamatch = vq,
48 .fn_kvm = kvm,
49 .fd = eventfd(0, 0),
50 };
51
52 if (vdev->use_vhost)
53 /*
54 * Vhost will poll the eventfd in host kernel side,
55 * no need to poll in userspace.
56 */
57 err = ioeventfd__add_event(&ioevent, 0);
58 else
59 /* Need to poll in userspace. */
60 err = ioeventfd__add_event(&ioevent, IOEVENTFD_FLAG_USER_POLL);
61 if (err)
62 return err;
63
64 if (vdev->ops->notify_vq_eventfd)
65 vdev->ops->notify_vq_eventfd(kvm, vmmio->dev, vq, ioevent.fd);
66
67 return 0;
68 }
69
virtio_mmio_signal_vq(struct kvm * kvm,struct virtio_device * vdev,u32 vq)70 int virtio_mmio_signal_vq(struct kvm *kvm, struct virtio_device *vdev, u32 vq)
71 {
72 struct virtio_mmio *vmmio = vdev->virtio;
73
74 vmmio->hdr.interrupt_state |= VIRTIO_MMIO_INT_VRING;
75 kvm__irq_trigger(vmmio->kvm, vmmio->irq);
76
77 return 0;
78 }
79
virtio_mmio_init_vq(struct kvm * kvm,struct virtio_device * vdev,int vq)80 int virtio_mmio_init_vq(struct kvm *kvm, struct virtio_device *vdev, int vq)
81 {
82 int ret;
83 struct virtio_mmio *vmmio = vdev->virtio;
84
85 ret = virtio_mmio_init_ioeventfd(vmmio->kvm, vdev, vq);
86 if (ret) {
87 pr_err("couldn't add ioeventfd for vq %d: %d", vq, ret);
88 return ret;
89 }
90 return vdev->ops->init_vq(vmmio->kvm, vmmio->dev, vq);
91 }
92
virtio_mmio_exit_vq(struct kvm * kvm,struct virtio_device * vdev,int vq)93 void virtio_mmio_exit_vq(struct kvm *kvm, struct virtio_device *vdev, int vq)
94 {
95 struct virtio_mmio *vmmio = vdev->virtio;
96
97 ioeventfd__del_event(vmmio->addr + VIRTIO_MMIO_QUEUE_NOTIFY, vq);
98 virtio_exit_vq(kvm, vdev, vmmio->dev, vq);
99 }
100
virtio_mmio_signal_config(struct kvm * kvm,struct virtio_device * vdev)101 int virtio_mmio_signal_config(struct kvm *kvm, struct virtio_device *vdev)
102 {
103 struct virtio_mmio *vmmio = vdev->virtio;
104
105 vmmio->hdr.interrupt_state |= VIRTIO_MMIO_INT_CONFIG;
106 kvm__irq_trigger(vmmio->kvm, vmmio->irq);
107
108 return 0;
109 }
110
111 #ifdef CONFIG_HAS_LIBFDT
112 #define DEVICE_NAME_MAX_LEN 32
113 static
generate_virtio_mmio_fdt_node(void * fdt,struct device_header * dev_hdr,void (* generate_irq_prop)(void * fdt,u8 irq,enum irq_type))114 void generate_virtio_mmio_fdt_node(void *fdt,
115 struct device_header *dev_hdr,
116 void (*generate_irq_prop)(void *fdt,
117 u8 irq,
118 enum irq_type))
119 {
120 char dev_name[DEVICE_NAME_MAX_LEN];
121 struct virtio_mmio *vmmio = container_of(dev_hdr,
122 struct virtio_mmio,
123 dev_hdr);
124 u64 addr = vmmio->addr;
125 u64 reg_prop[] = {
126 cpu_to_fdt64(addr),
127 cpu_to_fdt64(VIRTIO_MMIO_IO_SIZE),
128 };
129
130 snprintf(dev_name, DEVICE_NAME_MAX_LEN, "virtio@%llx", addr);
131
132 _FDT(fdt_begin_node(fdt, dev_name));
133 _FDT(fdt_property_string(fdt, "compatible", "virtio,mmio"));
134 _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
135 _FDT(fdt_property(fdt, "dma-coherent", NULL, 0));
136 generate_irq_prop(fdt, vmmio->irq, IRQ_TYPE_EDGE_RISING);
137 _FDT(fdt_end_node(fdt));
138 }
139 #else
generate_virtio_mmio_fdt_node(void * fdt,struct device_header * dev_hdr,void (* generate_irq_prop)(void * fdt,u8 irq))140 static void generate_virtio_mmio_fdt_node(void *fdt,
141 struct device_header *dev_hdr,
142 void (*generate_irq_prop)(void *fdt,
143 u8 irq))
144 {
145 die("Unable to generate device tree nodes without libfdt\n");
146 }
147 #endif
148
virtio_mmio_init(struct kvm * kvm,void * dev,struct virtio_device * vdev,int device_id,int subsys_id,int class)149 int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
150 int device_id, int subsys_id, int class)
151 {
152 bool legacy = vdev->legacy;
153 struct virtio_mmio *vmmio = vdev->virtio;
154 int r;
155
156 vmmio->addr = virtio_mmio_get_io_space_block(VIRTIO_MMIO_IO_SIZE);
157 vmmio->kvm = kvm;
158 vmmio->dev = dev;
159
160 if (!legacy)
161 vdev->endian = VIRTIO_ENDIAN_LE;
162
163 r = kvm__register_mmio(kvm, vmmio->addr, VIRTIO_MMIO_IO_SIZE, false,
164 legacy ? virtio_mmio_legacy_callback :
165 virtio_mmio_modern_callback,
166 vdev);
167 if (r < 0)
168 return r;
169
170 vmmio->hdr = (struct virtio_mmio_hdr) {
171 .magic = {'v', 'i', 'r', 't'},
172 .version = legacy ? 1 : 2,
173 .device_id = subsys_id,
174 .vendor_id = 0x4d564b4c , /* 'LKVM' */
175 .queue_num_max = 256,
176 };
177
178 vmmio->dev_hdr = (struct device_header) {
179 .bus_type = DEVICE_BUS_MMIO,
180 .data = generate_virtio_mmio_fdt_node,
181 };
182
183 vmmio->irq = irq__alloc_line();
184
185 r = device__register(&vmmio->dev_hdr);
186 if (r < 0) {
187 kvm__deregister_mmio(kvm, vmmio->addr);
188 return r;
189 }
190
191 /*
192 * Instantiate guest virtio-mmio devices using kernel command line
193 * (or module) parameter, e.g
194 *
195 * virtio_mmio.devices=0x200@0xd2000000:5,0x200@0xd2000200:6
196 */
197 pr_debug("virtio-mmio.devices=0x%x@0x%x:%d", VIRTIO_MMIO_IO_SIZE,
198 vmmio->addr, vmmio->irq);
199
200 return 0;
201 }
202
virtio_mmio_reset(struct kvm * kvm,struct virtio_device * vdev)203 int virtio_mmio_reset(struct kvm *kvm, struct virtio_device *vdev)
204 {
205 unsigned int vq;
206 struct virtio_mmio *vmmio = vdev->virtio;
207
208 for (vq = 0; vq < vdev->ops->get_vq_count(kvm, vmmio->dev); vq++)
209 virtio_mmio_exit_vq(kvm, vdev, vq);
210
211 return 0;
212 }
213
virtio_mmio_exit(struct kvm * kvm,struct virtio_device * vdev)214 int virtio_mmio_exit(struct kvm *kvm, struct virtio_device *vdev)
215 {
216 struct virtio_mmio *vmmio = vdev->virtio;
217
218 virtio_mmio_reset(kvm, vdev);
219 kvm__deregister_mmio(kvm, vmmio->addr);
220
221 return 0;
222 }
223