virtio-iommu.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. /*
  2. * virtio-iommu device
  3. *
  4. * Copyright (c) 2020 Red Hat, Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public License,
  8. * version 2 or later, as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along with
  16. * this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. #include "qemu/osdep.h"
  20. #include "qemu/log.h"
  21. #include "qemu/iov.h"
  22. #include "qemu-common.h"
  23. #include "hw/qdev-properties.h"
  24. #include "hw/virtio/virtio.h"
  25. #include "sysemu/kvm.h"
  26. #include "qapi/error.h"
  27. #include "qemu/error-report.h"
  28. #include "trace.h"
  29. #include "standard-headers/linux/virtio_ids.h"
  30. #include "hw/virtio/virtio-bus.h"
  31. #include "hw/virtio/virtio-access.h"
  32. #include "hw/virtio/virtio-iommu.h"
  33. #include "hw/pci/pci_bus.h"
  34. #include "hw/pci/pci.h"
  35. /* Max size */
  36. #define VIOMMU_DEFAULT_QUEUE_SIZE 256
  37. #define VIOMMU_PROBE_SIZE 512
  38. typedef struct VirtIOIOMMUDomain {
  39. uint32_t id;
  40. GTree *mappings;
  41. QLIST_HEAD(, VirtIOIOMMUEndpoint) endpoint_list;
  42. } VirtIOIOMMUDomain;
  43. typedef struct VirtIOIOMMUEndpoint {
  44. uint32_t id;
  45. VirtIOIOMMUDomain *domain;
  46. QLIST_ENTRY(VirtIOIOMMUEndpoint) next;
  47. } VirtIOIOMMUEndpoint;
  48. typedef struct VirtIOIOMMUInterval {
  49. uint64_t low;
  50. uint64_t high;
  51. } VirtIOIOMMUInterval;
  52. typedef struct VirtIOIOMMUMapping {
  53. uint64_t phys_addr;
  54. uint32_t flags;
  55. } VirtIOIOMMUMapping;
  56. static inline uint16_t virtio_iommu_get_bdf(IOMMUDevice *dev)
  57. {
  58. return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn);
  59. }
  60. /**
  61. * The bus number is used for lookup when SID based operations occur.
  62. * In that case we lazily populate the IOMMUPciBus array from the bus hash
  63. * table. At the time the IOMMUPciBus is created (iommu_find_add_as), the bus
  64. * numbers may not be always initialized yet.
  65. */
  66. static IOMMUPciBus *iommu_find_iommu_pcibus(VirtIOIOMMU *s, uint8_t bus_num)
  67. {
  68. IOMMUPciBus *iommu_pci_bus = s->iommu_pcibus_by_bus_num[bus_num];
  69. if (!iommu_pci_bus) {
  70. GHashTableIter iter;
  71. g_hash_table_iter_init(&iter, s->as_by_busptr);
  72. while (g_hash_table_iter_next(&iter, NULL, (void **)&iommu_pci_bus)) {
  73. if (pci_bus_num(iommu_pci_bus->bus) == bus_num) {
  74. s->iommu_pcibus_by_bus_num[bus_num] = iommu_pci_bus;
  75. return iommu_pci_bus;
  76. }
  77. }
  78. return NULL;
  79. }
  80. return iommu_pci_bus;
  81. }
  82. static IOMMUMemoryRegion *virtio_iommu_mr(VirtIOIOMMU *s, uint32_t sid)
  83. {
  84. uint8_t bus_n, devfn;
  85. IOMMUPciBus *iommu_pci_bus;
  86. IOMMUDevice *dev;
  87. bus_n = PCI_BUS_NUM(sid);
  88. iommu_pci_bus = iommu_find_iommu_pcibus(s, bus_n);
  89. if (iommu_pci_bus) {
  90. devfn = sid & PCI_DEVFN_MAX;
  91. dev = iommu_pci_bus->pbdev[devfn];
  92. if (dev) {
  93. return &dev->iommu_mr;
  94. }
  95. }
  96. return NULL;
  97. }
  98. static gint interval_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
  99. {
  100. VirtIOIOMMUInterval *inta = (VirtIOIOMMUInterval *)a;
  101. VirtIOIOMMUInterval *intb = (VirtIOIOMMUInterval *)b;
  102. if (inta->high < intb->low) {
  103. return -1;
  104. } else if (intb->high < inta->low) {
  105. return 1;
  106. } else {
  107. return 0;
  108. }
  109. }
  110. static void virtio_iommu_detach_endpoint_from_domain(VirtIOIOMMUEndpoint *ep)
  111. {
  112. if (!ep->domain) {
  113. return;
  114. }
  115. QLIST_REMOVE(ep, next);
  116. ep->domain = NULL;
  117. }
  118. static VirtIOIOMMUEndpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s,
  119. uint32_t ep_id)
  120. {
  121. VirtIOIOMMUEndpoint *ep;
  122. ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id));
  123. if (ep) {
  124. return ep;
  125. }
  126. if (!virtio_iommu_mr(s, ep_id)) {
  127. return NULL;
  128. }
  129. ep = g_malloc0(sizeof(*ep));
  130. ep->id = ep_id;
  131. trace_virtio_iommu_get_endpoint(ep_id);
  132. g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep);
  133. return ep;
  134. }
  135. static void virtio_iommu_put_endpoint(gpointer data)
  136. {
  137. VirtIOIOMMUEndpoint *ep = (VirtIOIOMMUEndpoint *)data;
  138. if (ep->domain) {
  139. virtio_iommu_detach_endpoint_from_domain(ep);
  140. }
  141. trace_virtio_iommu_put_endpoint(ep->id);
  142. g_free(ep);
  143. }
  144. static VirtIOIOMMUDomain *virtio_iommu_get_domain(VirtIOIOMMU *s,
  145. uint32_t domain_id)
  146. {
  147. VirtIOIOMMUDomain *domain;
  148. domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id));
  149. if (domain) {
  150. return domain;
  151. }
  152. domain = g_malloc0(sizeof(*domain));
  153. domain->id = domain_id;
  154. domain->mappings = g_tree_new_full((GCompareDataFunc)interval_cmp,
  155. NULL, (GDestroyNotify)g_free,
  156. (GDestroyNotify)g_free);
  157. g_tree_insert(s->domains, GUINT_TO_POINTER(domain_id), domain);
  158. QLIST_INIT(&domain->endpoint_list);
  159. trace_virtio_iommu_get_domain(domain_id);
  160. return domain;
  161. }
  162. static void virtio_iommu_put_domain(gpointer data)
  163. {
  164. VirtIOIOMMUDomain *domain = (VirtIOIOMMUDomain *)data;
  165. VirtIOIOMMUEndpoint *iter, *tmp;
  166. QLIST_FOREACH_SAFE(iter, &domain->endpoint_list, next, tmp) {
  167. virtio_iommu_detach_endpoint_from_domain(iter);
  168. }
  169. g_tree_destroy(domain->mappings);
  170. trace_virtio_iommu_put_domain(domain->id);
  171. g_free(domain);
  172. }
  173. static AddressSpace *virtio_iommu_find_add_as(PCIBus *bus, void *opaque,
  174. int devfn)
  175. {
  176. VirtIOIOMMU *s = opaque;
  177. IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus);
  178. static uint32_t mr_index;
  179. IOMMUDevice *sdev;
  180. if (!sbus) {
  181. sbus = g_malloc0(sizeof(IOMMUPciBus) +
  182. sizeof(IOMMUDevice *) * PCI_DEVFN_MAX);
  183. sbus->bus = bus;
  184. g_hash_table_insert(s->as_by_busptr, bus, sbus);
  185. }
  186. sdev = sbus->pbdev[devfn];
  187. if (!sdev) {
  188. char *name = g_strdup_printf("%s-%d-%d",
  189. TYPE_VIRTIO_IOMMU_MEMORY_REGION,
  190. mr_index++, devfn);
  191. sdev = sbus->pbdev[devfn] = g_malloc0(sizeof(IOMMUDevice));
  192. sdev->viommu = s;
  193. sdev->bus = bus;
  194. sdev->devfn = devfn;
  195. trace_virtio_iommu_init_iommu_mr(name);
  196. memory_region_init_iommu(&sdev->iommu_mr, sizeof(sdev->iommu_mr),
  197. TYPE_VIRTIO_IOMMU_MEMORY_REGION,
  198. OBJECT(s), name,
  199. UINT64_MAX);
  200. address_space_init(&sdev->as,
  201. MEMORY_REGION(&sdev->iommu_mr), TYPE_VIRTIO_IOMMU);
  202. g_free(name);
  203. }
  204. return &sdev->as;
  205. }
  206. static int virtio_iommu_attach(VirtIOIOMMU *s,
  207. struct virtio_iommu_req_attach *req)
  208. {
  209. uint32_t domain_id = le32_to_cpu(req->domain);
  210. uint32_t ep_id = le32_to_cpu(req->endpoint);
  211. VirtIOIOMMUDomain *domain;
  212. VirtIOIOMMUEndpoint *ep;
  213. trace_virtio_iommu_attach(domain_id, ep_id);
  214. ep = virtio_iommu_get_endpoint(s, ep_id);
  215. if (!ep) {
  216. return VIRTIO_IOMMU_S_NOENT;
  217. }
  218. if (ep->domain) {
  219. VirtIOIOMMUDomain *previous_domain = ep->domain;
  220. /*
  221. * the device is already attached to a domain,
  222. * detach it first
  223. */
  224. virtio_iommu_detach_endpoint_from_domain(ep);
  225. if (QLIST_EMPTY(&previous_domain->endpoint_list)) {
  226. g_tree_remove(s->domains, GUINT_TO_POINTER(previous_domain->id));
  227. }
  228. }
  229. domain = virtio_iommu_get_domain(s, domain_id);
  230. QLIST_INSERT_HEAD(&domain->endpoint_list, ep, next);
  231. ep->domain = domain;
  232. return VIRTIO_IOMMU_S_OK;
  233. }
  234. static int virtio_iommu_detach(VirtIOIOMMU *s,
  235. struct virtio_iommu_req_detach *req)
  236. {
  237. uint32_t domain_id = le32_to_cpu(req->domain);
  238. uint32_t ep_id = le32_to_cpu(req->endpoint);
  239. VirtIOIOMMUDomain *domain;
  240. VirtIOIOMMUEndpoint *ep;
  241. trace_virtio_iommu_detach(domain_id, ep_id);
  242. ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id));
  243. if (!ep) {
  244. return VIRTIO_IOMMU_S_NOENT;
  245. }
  246. domain = ep->domain;
  247. if (!domain || domain->id != domain_id) {
  248. return VIRTIO_IOMMU_S_INVAL;
  249. }
  250. virtio_iommu_detach_endpoint_from_domain(ep);
  251. if (QLIST_EMPTY(&domain->endpoint_list)) {
  252. g_tree_remove(s->domains, GUINT_TO_POINTER(domain->id));
  253. }
  254. return VIRTIO_IOMMU_S_OK;
  255. }
  256. static int virtio_iommu_map(VirtIOIOMMU *s,
  257. struct virtio_iommu_req_map *req)
  258. {
  259. uint32_t domain_id = le32_to_cpu(req->domain);
  260. uint64_t phys_start = le64_to_cpu(req->phys_start);
  261. uint64_t virt_start = le64_to_cpu(req->virt_start);
  262. uint64_t virt_end = le64_to_cpu(req->virt_end);
  263. uint32_t flags = le32_to_cpu(req->flags);
  264. VirtIOIOMMUDomain *domain;
  265. VirtIOIOMMUInterval *interval;
  266. VirtIOIOMMUMapping *mapping;
  267. if (flags & ~VIRTIO_IOMMU_MAP_F_MASK) {
  268. return VIRTIO_IOMMU_S_INVAL;
  269. }
  270. domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id));
  271. if (!domain) {
  272. return VIRTIO_IOMMU_S_NOENT;
  273. }
  274. interval = g_malloc0(sizeof(*interval));
  275. interval->low = virt_start;
  276. interval->high = virt_end;
  277. mapping = g_tree_lookup(domain->mappings, (gpointer)interval);
  278. if (mapping) {
  279. g_free(interval);
  280. return VIRTIO_IOMMU_S_INVAL;
  281. }
  282. trace_virtio_iommu_map(domain_id, virt_start, virt_end, phys_start, flags);
  283. mapping = g_malloc0(sizeof(*mapping));
  284. mapping->phys_addr = phys_start;
  285. mapping->flags = flags;
  286. g_tree_insert(domain->mappings, interval, mapping);
  287. return VIRTIO_IOMMU_S_OK;
  288. }
  289. static int virtio_iommu_unmap(VirtIOIOMMU *s,
  290. struct virtio_iommu_req_unmap *req)
  291. {
  292. uint32_t domain_id = le32_to_cpu(req->domain);
  293. uint64_t virt_start = le64_to_cpu(req->virt_start);
  294. uint64_t virt_end = le64_to_cpu(req->virt_end);
  295. VirtIOIOMMUMapping *iter_val;
  296. VirtIOIOMMUInterval interval, *iter_key;
  297. VirtIOIOMMUDomain *domain;
  298. int ret = VIRTIO_IOMMU_S_OK;
  299. trace_virtio_iommu_unmap(domain_id, virt_start, virt_end);
  300. domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id));
  301. if (!domain) {
  302. return VIRTIO_IOMMU_S_NOENT;
  303. }
  304. interval.low = virt_start;
  305. interval.high = virt_end;
  306. while (g_tree_lookup_extended(domain->mappings, &interval,
  307. (void **)&iter_key, (void**)&iter_val)) {
  308. uint64_t current_low = iter_key->low;
  309. uint64_t current_high = iter_key->high;
  310. if (interval.low <= current_low && interval.high >= current_high) {
  311. g_tree_remove(domain->mappings, iter_key);
  312. trace_virtio_iommu_unmap_done(domain_id, current_low, current_high);
  313. } else {
  314. ret = VIRTIO_IOMMU_S_RANGE;
  315. break;
  316. }
  317. }
  318. return ret;
  319. }
  320. static ssize_t virtio_iommu_fill_resv_mem_prop(VirtIOIOMMU *s, uint32_t ep,
  321. uint8_t *buf, size_t free)
  322. {
  323. struct virtio_iommu_probe_resv_mem prop = {};
  324. size_t size = sizeof(prop), length = size - sizeof(prop.head), total;
  325. int i;
  326. total = size * s->nb_reserved_regions;
  327. if (total > free) {
  328. return -ENOSPC;
  329. }
  330. for (i = 0; i < s->nb_reserved_regions; i++) {
  331. unsigned subtype = s->reserved_regions[i].type;
  332. assert(subtype == VIRTIO_IOMMU_RESV_MEM_T_RESERVED ||
  333. subtype == VIRTIO_IOMMU_RESV_MEM_T_MSI);
  334. prop.head.type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM);
  335. prop.head.length = cpu_to_le16(length);
  336. prop.subtype = subtype;
  337. prop.start = cpu_to_le64(s->reserved_regions[i].low);
  338. prop.end = cpu_to_le64(s->reserved_regions[i].high);
  339. memcpy(buf, &prop, size);
  340. trace_virtio_iommu_fill_resv_property(ep, prop.subtype,
  341. prop.start, prop.end);
  342. buf += size;
  343. }
  344. return total;
  345. }
  346. /**
  347. * virtio_iommu_probe - Fill the probe request buffer with
  348. * the properties the device is able to return
  349. */
  350. static int virtio_iommu_probe(VirtIOIOMMU *s,
  351. struct virtio_iommu_req_probe *req,
  352. uint8_t *buf)
  353. {
  354. uint32_t ep_id = le32_to_cpu(req->endpoint);
  355. size_t free = VIOMMU_PROBE_SIZE;
  356. ssize_t count;
  357. if (!virtio_iommu_mr(s, ep_id)) {
  358. return VIRTIO_IOMMU_S_NOENT;
  359. }
  360. count = virtio_iommu_fill_resv_mem_prop(s, ep_id, buf, free);
  361. if (count < 0) {
  362. return VIRTIO_IOMMU_S_INVAL;
  363. }
  364. buf += count;
  365. free -= count;
  366. return VIRTIO_IOMMU_S_OK;
  367. }
  368. static int virtio_iommu_iov_to_req(struct iovec *iov,
  369. unsigned int iov_cnt,
  370. void *req, size_t req_sz)
  371. {
  372. size_t sz, payload_sz = req_sz - sizeof(struct virtio_iommu_req_tail);
  373. sz = iov_to_buf(iov, iov_cnt, 0, req, payload_sz);
  374. if (unlikely(sz != payload_sz)) {
  375. return VIRTIO_IOMMU_S_INVAL;
  376. }
  377. return 0;
  378. }
  379. #define virtio_iommu_handle_req(__req) \
  380. static int virtio_iommu_handle_ ## __req(VirtIOIOMMU *s, \
  381. struct iovec *iov, \
  382. unsigned int iov_cnt) \
  383. { \
  384. struct virtio_iommu_req_ ## __req req; \
  385. int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); \
  386. \
  387. return ret ? ret : virtio_iommu_ ## __req(s, &req); \
  388. }
  389. virtio_iommu_handle_req(attach)
  390. virtio_iommu_handle_req(detach)
  391. virtio_iommu_handle_req(map)
  392. virtio_iommu_handle_req(unmap)
  393. static int virtio_iommu_handle_probe(VirtIOIOMMU *s,
  394. struct iovec *iov,
  395. unsigned int iov_cnt,
  396. uint8_t *buf)
  397. {
  398. struct virtio_iommu_req_probe req;
  399. int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req));
  400. return ret ? ret : virtio_iommu_probe(s, &req, buf);
  401. }
  402. static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
  403. {
  404. VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
  405. struct virtio_iommu_req_head head;
  406. struct virtio_iommu_req_tail tail = {};
  407. size_t output_size = sizeof(tail), sz;
  408. VirtQueueElement *elem;
  409. unsigned int iov_cnt;
  410. struct iovec *iov;
  411. void *buf = NULL;
  412. for (;;) {
  413. elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
  414. if (!elem) {
  415. return;
  416. }
  417. if (iov_size(elem->in_sg, elem->in_num) < sizeof(tail) ||
  418. iov_size(elem->out_sg, elem->out_num) < sizeof(head)) {
  419. virtio_error(vdev, "virtio-iommu bad head/tail size");
  420. virtqueue_detach_element(vq, elem, 0);
  421. g_free(elem);
  422. break;
  423. }
  424. iov_cnt = elem->out_num;
  425. iov = elem->out_sg;
  426. sz = iov_to_buf(iov, iov_cnt, 0, &head, sizeof(head));
  427. if (unlikely(sz != sizeof(head))) {
  428. tail.status = VIRTIO_IOMMU_S_DEVERR;
  429. goto out;
  430. }
  431. qemu_mutex_lock(&s->mutex);
  432. switch (head.type) {
  433. case VIRTIO_IOMMU_T_ATTACH:
  434. tail.status = virtio_iommu_handle_attach(s, iov, iov_cnt);
  435. break;
  436. case VIRTIO_IOMMU_T_DETACH:
  437. tail.status = virtio_iommu_handle_detach(s, iov, iov_cnt);
  438. break;
  439. case VIRTIO_IOMMU_T_MAP:
  440. tail.status = virtio_iommu_handle_map(s, iov, iov_cnt);
  441. break;
  442. case VIRTIO_IOMMU_T_UNMAP:
  443. tail.status = virtio_iommu_handle_unmap(s, iov, iov_cnt);
  444. break;
  445. case VIRTIO_IOMMU_T_PROBE:
  446. {
  447. struct virtio_iommu_req_tail *ptail;
  448. output_size = s->config.probe_size + sizeof(tail);
  449. buf = g_malloc0(output_size);
  450. ptail = (struct virtio_iommu_req_tail *)
  451. (buf + s->config.probe_size);
  452. ptail->status = virtio_iommu_handle_probe(s, iov, iov_cnt, buf);
  453. break;
  454. }
  455. default:
  456. tail.status = VIRTIO_IOMMU_S_UNSUPP;
  457. }
  458. qemu_mutex_unlock(&s->mutex);
  459. out:
  460. sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
  461. buf ? buf : &tail, output_size);
  462. assert(sz == output_size);
  463. virtqueue_push(vq, elem, sz);
  464. virtio_notify(vdev, vq);
  465. g_free(elem);
  466. g_free(buf);
  467. }
  468. }
  469. static void virtio_iommu_report_fault(VirtIOIOMMU *viommu, uint8_t reason,
  470. int flags, uint32_t endpoint,
  471. uint64_t address)
  472. {
  473. VirtIODevice *vdev = &viommu->parent_obj;
  474. VirtQueue *vq = viommu->event_vq;
  475. struct virtio_iommu_fault fault;
  476. VirtQueueElement *elem;
  477. size_t sz;
  478. memset(&fault, 0, sizeof(fault));
  479. fault.reason = reason;
  480. fault.flags = cpu_to_le32(flags);
  481. fault.endpoint = cpu_to_le32(endpoint);
  482. fault.address = cpu_to_le64(address);
  483. elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
  484. if (!elem) {
  485. error_report_once(
  486. "no buffer available in event queue to report event");
  487. return;
  488. }
  489. if (iov_size(elem->in_sg, elem->in_num) < sizeof(fault)) {
  490. virtio_error(vdev, "error buffer of wrong size");
  491. virtqueue_detach_element(vq, elem, 0);
  492. g_free(elem);
  493. return;
  494. }
  495. sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
  496. &fault, sizeof(fault));
  497. assert(sz == sizeof(fault));
  498. trace_virtio_iommu_report_fault(reason, flags, endpoint, address);
  499. virtqueue_push(vq, elem, sz);
  500. virtio_notify(vdev, vq);
  501. g_free(elem);
  502. }
  503. static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
  504. IOMMUAccessFlags flag,
  505. int iommu_idx)
  506. {
  507. IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr);
  508. VirtIOIOMMUInterval interval, *mapping_key;
  509. VirtIOIOMMUMapping *mapping_value;
  510. VirtIOIOMMU *s = sdev->viommu;
  511. bool read_fault, write_fault;
  512. VirtIOIOMMUEndpoint *ep;
  513. uint32_t sid, flags;
  514. bool bypass_allowed;
  515. bool found;
  516. int i;
  517. interval.low = addr;
  518. interval.high = addr + 1;
  519. IOMMUTLBEntry entry = {
  520. .target_as = &address_space_memory,
  521. .iova = addr,
  522. .translated_addr = addr,
  523. .addr_mask = (1 << ctz32(s->config.page_size_mask)) - 1,
  524. .perm = IOMMU_NONE,
  525. };
  526. bypass_allowed = virtio_vdev_has_feature(&s->parent_obj,
  527. VIRTIO_IOMMU_F_BYPASS);
  528. sid = virtio_iommu_get_bdf(sdev);
  529. trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag);
  530. qemu_mutex_lock(&s->mutex);
  531. ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(sid));
  532. if (!ep) {
  533. if (!bypass_allowed) {
  534. error_report_once("%s sid=%d is not known!!", __func__, sid);
  535. virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_UNKNOWN,
  536. VIRTIO_IOMMU_FAULT_F_ADDRESS,
  537. sid, addr);
  538. } else {
  539. entry.perm = flag;
  540. }
  541. goto unlock;
  542. }
  543. for (i = 0; i < s->nb_reserved_regions; i++) {
  544. ReservedRegion *reg = &s->reserved_regions[i];
  545. if (addr >= reg->low && addr <= reg->high) {
  546. switch (reg->type) {
  547. case VIRTIO_IOMMU_RESV_MEM_T_MSI:
  548. entry.perm = flag;
  549. break;
  550. case VIRTIO_IOMMU_RESV_MEM_T_RESERVED:
  551. default:
  552. virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING,
  553. VIRTIO_IOMMU_FAULT_F_ADDRESS,
  554. sid, addr);
  555. break;
  556. }
  557. goto unlock;
  558. }
  559. }
  560. if (!ep->domain) {
  561. if (!bypass_allowed) {
  562. error_report_once("%s %02x:%02x.%01x not attached to any domain",
  563. __func__, PCI_BUS_NUM(sid),
  564. PCI_SLOT(sid), PCI_FUNC(sid));
  565. virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_DOMAIN,
  566. VIRTIO_IOMMU_FAULT_F_ADDRESS,
  567. sid, addr);
  568. } else {
  569. entry.perm = flag;
  570. }
  571. goto unlock;
  572. }
  573. found = g_tree_lookup_extended(ep->domain->mappings, (gpointer)(&interval),
  574. (void **)&mapping_key,
  575. (void **)&mapping_value);
  576. if (!found) {
  577. error_report_once("%s no mapping for 0x%"PRIx64" for sid=%d",
  578. __func__, addr, sid);
  579. virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING,
  580. VIRTIO_IOMMU_FAULT_F_ADDRESS,
  581. sid, addr);
  582. goto unlock;
  583. }
  584. read_fault = (flag & IOMMU_RO) &&
  585. !(mapping_value->flags & VIRTIO_IOMMU_MAP_F_READ);
  586. write_fault = (flag & IOMMU_WO) &&
  587. !(mapping_value->flags & VIRTIO_IOMMU_MAP_F_WRITE);
  588. flags = read_fault ? VIRTIO_IOMMU_FAULT_F_READ : 0;
  589. flags |= write_fault ? VIRTIO_IOMMU_FAULT_F_WRITE : 0;
  590. if (flags) {
  591. error_report_once("%s permission error on 0x%"PRIx64"(%d): allowed=%d",
  592. __func__, addr, flag, mapping_value->flags);
  593. flags |= VIRTIO_IOMMU_FAULT_F_ADDRESS;
  594. virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING,
  595. flags | VIRTIO_IOMMU_FAULT_F_ADDRESS,
  596. sid, addr);
  597. goto unlock;
  598. }
  599. entry.translated_addr = addr - mapping_key->low + mapping_value->phys_addr;
  600. entry.perm = flag;
  601. trace_virtio_iommu_translate_out(addr, entry.translated_addr, sid);
  602. unlock:
  603. qemu_mutex_unlock(&s->mutex);
  604. return entry;
  605. }
  606. static void virtio_iommu_get_config(VirtIODevice *vdev, uint8_t *config_data)
  607. {
  608. VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev);
  609. struct virtio_iommu_config *config = &dev->config;
  610. trace_virtio_iommu_get_config(config->page_size_mask,
  611. config->input_range.start,
  612. config->input_range.end,
  613. config->domain_range.end,
  614. config->probe_size);
  615. memcpy(config_data, &dev->config, sizeof(struct virtio_iommu_config));
  616. }
  617. static void virtio_iommu_set_config(VirtIODevice *vdev,
  618. const uint8_t *config_data)
  619. {
  620. struct virtio_iommu_config config;
  621. memcpy(&config, config_data, sizeof(struct virtio_iommu_config));
  622. trace_virtio_iommu_set_config(config.page_size_mask,
  623. config.input_range.start,
  624. config.input_range.end,
  625. config.domain_range.end,
  626. config.probe_size);
  627. }
  628. static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f,
  629. Error **errp)
  630. {
  631. VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev);
  632. f |= dev->features;
  633. trace_virtio_iommu_get_features(f);
  634. return f;
  635. }
  636. static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
  637. {
  638. guint ua = GPOINTER_TO_UINT(a);
  639. guint ub = GPOINTER_TO_UINT(b);
  640. return (ua > ub) - (ua < ub);
  641. }
  642. static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
  643. {
  644. VirtIODevice *vdev = VIRTIO_DEVICE(dev);
  645. VirtIOIOMMU *s = VIRTIO_IOMMU(dev);
  646. virtio_init(vdev, "virtio-iommu", VIRTIO_ID_IOMMU,
  647. sizeof(struct virtio_iommu_config));
  648. memset(s->iommu_pcibus_by_bus_num, 0, sizeof(s->iommu_pcibus_by_bus_num));
  649. s->req_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE,
  650. virtio_iommu_handle_command);
  651. s->event_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL);
  652. s->config.page_size_mask = TARGET_PAGE_MASK;
  653. s->config.input_range.end = -1UL;
  654. s->config.domain_range.end = 32;
  655. s->config.probe_size = VIOMMU_PROBE_SIZE;
  656. virtio_add_feature(&s->features, VIRTIO_RING_F_EVENT_IDX);
  657. virtio_add_feature(&s->features, VIRTIO_RING_F_INDIRECT_DESC);
  658. virtio_add_feature(&s->features, VIRTIO_F_VERSION_1);
  659. virtio_add_feature(&s->features, VIRTIO_IOMMU_F_INPUT_RANGE);
  660. virtio_add_feature(&s->features, VIRTIO_IOMMU_F_DOMAIN_RANGE);
  661. virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP);
  662. virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS);
  663. virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MMIO);
  664. virtio_add_feature(&s->features, VIRTIO_IOMMU_F_PROBE);
  665. qemu_mutex_init(&s->mutex);
  666. s->as_by_busptr = g_hash_table_new_full(NULL, NULL, NULL, g_free);
  667. if (s->primary_bus) {
  668. pci_setup_iommu(s->primary_bus, virtio_iommu_find_add_as, s);
  669. } else {
  670. error_setg(errp, "VIRTIO-IOMMU is not attached to any PCI bus!");
  671. }
  672. }
  673. static void virtio_iommu_device_unrealize(DeviceState *dev)
  674. {
  675. VirtIODevice *vdev = VIRTIO_DEVICE(dev);
  676. VirtIOIOMMU *s = VIRTIO_IOMMU(dev);
  677. g_hash_table_destroy(s->as_by_busptr);
  678. g_tree_destroy(s->domains);
  679. g_tree_destroy(s->endpoints);
  680. virtio_delete_queue(s->req_vq);
  681. virtio_delete_queue(s->event_vq);
  682. virtio_cleanup(vdev);
  683. }
  684. static void virtio_iommu_device_reset(VirtIODevice *vdev)
  685. {
  686. VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
  687. trace_virtio_iommu_device_reset();
  688. if (s->domains) {
  689. g_tree_destroy(s->domains);
  690. }
  691. if (s->endpoints) {
  692. g_tree_destroy(s->endpoints);
  693. }
  694. s->domains = g_tree_new_full((GCompareDataFunc)int_cmp,
  695. NULL, NULL, virtio_iommu_put_domain);
  696. s->endpoints = g_tree_new_full((GCompareDataFunc)int_cmp,
  697. NULL, NULL, virtio_iommu_put_endpoint);
  698. }
  699. static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status)
  700. {
  701. trace_virtio_iommu_device_status(status);
  702. }
  703. static void virtio_iommu_instance_init(Object *obj)
  704. {
  705. }
  706. #define VMSTATE_INTERVAL \
  707. { \
  708. .name = "interval", \
  709. .version_id = 1, \
  710. .minimum_version_id = 1, \
  711. .fields = (VMStateField[]) { \
  712. VMSTATE_UINT64(low, VirtIOIOMMUInterval), \
  713. VMSTATE_UINT64(high, VirtIOIOMMUInterval), \
  714. VMSTATE_END_OF_LIST() \
  715. } \
  716. }
  717. #define VMSTATE_MAPPING \
  718. { \
  719. .name = "mapping", \
  720. .version_id = 1, \
  721. .minimum_version_id = 1, \
  722. .fields = (VMStateField[]) { \
  723. VMSTATE_UINT64(phys_addr, VirtIOIOMMUMapping),\
  724. VMSTATE_UINT32(flags, VirtIOIOMMUMapping), \
  725. VMSTATE_END_OF_LIST() \
  726. }, \
  727. }
  728. static const VMStateDescription vmstate_interval_mapping[2] = {
  729. VMSTATE_MAPPING, /* value */
  730. VMSTATE_INTERVAL /* key */
  731. };
  732. static int domain_preload(void *opaque)
  733. {
  734. VirtIOIOMMUDomain *domain = opaque;
  735. domain->mappings = g_tree_new_full((GCompareDataFunc)interval_cmp,
  736. NULL, g_free, g_free);
  737. return 0;
  738. }
  739. static const VMStateDescription vmstate_endpoint = {
  740. .name = "endpoint",
  741. .version_id = 1,
  742. .minimum_version_id = 1,
  743. .fields = (VMStateField[]) {
  744. VMSTATE_UINT32(id, VirtIOIOMMUEndpoint),
  745. VMSTATE_END_OF_LIST()
  746. }
  747. };
  748. static const VMStateDescription vmstate_domain = {
  749. .name = "domain",
  750. .version_id = 1,
  751. .minimum_version_id = 1,
  752. .pre_load = domain_preload,
  753. .fields = (VMStateField[]) {
  754. VMSTATE_UINT32(id, VirtIOIOMMUDomain),
  755. VMSTATE_GTREE_V(mappings, VirtIOIOMMUDomain, 1,
  756. vmstate_interval_mapping,
  757. VirtIOIOMMUInterval, VirtIOIOMMUMapping),
  758. VMSTATE_QLIST_V(endpoint_list, VirtIOIOMMUDomain, 1,
  759. vmstate_endpoint, VirtIOIOMMUEndpoint, next),
  760. VMSTATE_END_OF_LIST()
  761. }
  762. };
  763. static gboolean reconstruct_endpoints(gpointer key, gpointer value,
  764. gpointer data)
  765. {
  766. VirtIOIOMMU *s = (VirtIOIOMMU *)data;
  767. VirtIOIOMMUDomain *d = (VirtIOIOMMUDomain *)value;
  768. VirtIOIOMMUEndpoint *iter;
  769. QLIST_FOREACH(iter, &d->endpoint_list, next) {
  770. iter->domain = d;
  771. g_tree_insert(s->endpoints, GUINT_TO_POINTER(iter->id), iter);
  772. }
  773. return false; /* continue the domain traversal */
  774. }
  775. static int iommu_post_load(void *opaque, int version_id)
  776. {
  777. VirtIOIOMMU *s = opaque;
  778. g_tree_foreach(s->domains, reconstruct_endpoints, s);
  779. return 0;
  780. }
  781. static const VMStateDescription vmstate_virtio_iommu_device = {
  782. .name = "virtio-iommu-device",
  783. .minimum_version_id = 1,
  784. .version_id = 1,
  785. .post_load = iommu_post_load,
  786. .fields = (VMStateField[]) {
  787. VMSTATE_GTREE_DIRECT_KEY_V(domains, VirtIOIOMMU, 1,
  788. &vmstate_domain, VirtIOIOMMUDomain),
  789. VMSTATE_END_OF_LIST()
  790. },
  791. };
  792. static const VMStateDescription vmstate_virtio_iommu = {
  793. .name = "virtio-iommu",
  794. .minimum_version_id = 1,
  795. .priority = MIG_PRI_IOMMU,
  796. .version_id = 1,
  797. .fields = (VMStateField[]) {
  798. VMSTATE_VIRTIO_DEVICE,
  799. VMSTATE_END_OF_LIST()
  800. },
  801. };
  802. static Property virtio_iommu_properties[] = {
  803. DEFINE_PROP_LINK("primary-bus", VirtIOIOMMU, primary_bus, "PCI", PCIBus *),
  804. DEFINE_PROP_END_OF_LIST(),
  805. };
  806. static void virtio_iommu_class_init(ObjectClass *klass, void *data)
  807. {
  808. DeviceClass *dc = DEVICE_CLASS(klass);
  809. VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
  810. device_class_set_props(dc, virtio_iommu_properties);
  811. dc->vmsd = &vmstate_virtio_iommu;
  812. set_bit(DEVICE_CATEGORY_MISC, dc->categories);
  813. vdc->realize = virtio_iommu_device_realize;
  814. vdc->unrealize = virtio_iommu_device_unrealize;
  815. vdc->reset = virtio_iommu_device_reset;
  816. vdc->get_config = virtio_iommu_get_config;
  817. vdc->set_config = virtio_iommu_set_config;
  818. vdc->get_features = virtio_iommu_get_features;
  819. vdc->set_status = virtio_iommu_set_status;
  820. vdc->vmsd = &vmstate_virtio_iommu_device;
  821. }
  822. static void virtio_iommu_memory_region_class_init(ObjectClass *klass,
  823. void *data)
  824. {
  825. IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
  826. imrc->translate = virtio_iommu_translate;
  827. }
  828. static const TypeInfo virtio_iommu_info = {
  829. .name = TYPE_VIRTIO_IOMMU,
  830. .parent = TYPE_VIRTIO_DEVICE,
  831. .instance_size = sizeof(VirtIOIOMMU),
  832. .instance_init = virtio_iommu_instance_init,
  833. .class_init = virtio_iommu_class_init,
  834. };
  835. static const TypeInfo virtio_iommu_memory_region_info = {
  836. .parent = TYPE_IOMMU_MEMORY_REGION,
  837. .name = TYPE_VIRTIO_IOMMU_MEMORY_REGION,
  838. .class_init = virtio_iommu_memory_region_class_init,
  839. };
  840. static void virtio_register_types(void)
  841. {
  842. type_register_static(&virtio_iommu_info);
  843. type_register_static(&virtio_iommu_memory_region_info);
  844. }
  845. type_init(virtio_register_types)