amd_iommu.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  1. /*
  2. * QEMU emulation of AMD IOMMU (AMD-Vi)
  3. *
  4. * Copyright (C) 2011 Eduard - Gabriel Munteanu
  5. * Copyright (C) 2015 David Kiarie, <davidkiarie4@gmail.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * Cache implementation inspired by hw/i386/intel_iommu.c
  19. */
  20. #include "qemu/osdep.h"
  21. #include "hw/i386/pc.h"
  22. #include "hw/pci/msi.h"
  23. #include "hw/pci/pci_bus.h"
  24. #include "amd_iommu.h"
  25. #include "qapi/error.h"
  26. #include "qemu/error-report.h"
  27. #include "trace.h"
  28. /* used AMD-Vi MMIO registers */
  29. const char *amdvi_mmio_low[] = {
  30. "AMDVI_MMIO_DEVTAB_BASE",
  31. "AMDVI_MMIO_CMDBUF_BASE",
  32. "AMDVI_MMIO_EVTLOG_BASE",
  33. "AMDVI_MMIO_CONTROL",
  34. "AMDVI_MMIO_EXCL_BASE",
  35. "AMDVI_MMIO_EXCL_LIMIT",
  36. "AMDVI_MMIO_EXT_FEATURES",
  37. "AMDVI_MMIO_PPR_BASE",
  38. "UNHANDLED"
  39. };
  40. const char *amdvi_mmio_high[] = {
  41. "AMDVI_MMIO_COMMAND_HEAD",
  42. "AMDVI_MMIO_COMMAND_TAIL",
  43. "AMDVI_MMIO_EVTLOG_HEAD",
  44. "AMDVI_MMIO_EVTLOG_TAIL",
  45. "AMDVI_MMIO_STATUS",
  46. "AMDVI_MMIO_PPR_HEAD",
  47. "AMDVI_MMIO_PPR_TAIL",
  48. "UNHANDLED"
  49. };
  50. struct AMDVIAddressSpace {
  51. uint8_t bus_num; /* bus number */
  52. uint8_t devfn; /* device function */
  53. AMDVIState *iommu_state; /* AMDVI - one per machine */
  54. IOMMUMemoryRegion iommu; /* Device's address translation region */
  55. MemoryRegion iommu_ir; /* Device's interrupt remapping region */
  56. AddressSpace as; /* device's corresponding address space */
  57. };
  58. /* AMDVI cache entry */
  59. typedef struct AMDVIIOTLBEntry {
  60. uint16_t domid; /* assigned domain id */
  61. uint16_t devid; /* device owning entry */
  62. uint64_t perms; /* access permissions */
  63. uint64_t translated_addr; /* translated address */
  64. uint64_t page_mask; /* physical page size */
  65. } AMDVIIOTLBEntry;
  66. /* configure MMIO registers at startup/reset */
  67. static void amdvi_set_quad(AMDVIState *s, hwaddr addr, uint64_t val,
  68. uint64_t romask, uint64_t w1cmask)
  69. {
  70. stq_le_p(&s->mmior[addr], val);
  71. stq_le_p(&s->romask[addr], romask);
  72. stq_le_p(&s->w1cmask[addr], w1cmask);
  73. }
  74. static uint16_t amdvi_readw(AMDVIState *s, hwaddr addr)
  75. {
  76. return lduw_le_p(&s->mmior[addr]);
  77. }
  78. static uint32_t amdvi_readl(AMDVIState *s, hwaddr addr)
  79. {
  80. return ldl_le_p(&s->mmior[addr]);
  81. }
  82. static uint64_t amdvi_readq(AMDVIState *s, hwaddr addr)
  83. {
  84. return ldq_le_p(&s->mmior[addr]);
  85. }
  86. /* internal write */
  87. static void amdvi_writeq_raw(AMDVIState *s, uint64_t val, hwaddr addr)
  88. {
  89. stq_le_p(&s->mmior[addr], val);
  90. }
  91. /* external write */
  92. static void amdvi_writew(AMDVIState *s, hwaddr addr, uint16_t val)
  93. {
  94. uint16_t romask = lduw_le_p(&s->romask[addr]);
  95. uint16_t w1cmask = lduw_le_p(&s->w1cmask[addr]);
  96. uint16_t oldval = lduw_le_p(&s->mmior[addr]);
  97. stw_le_p(&s->mmior[addr],
  98. ((oldval & romask) | (val & ~romask)) & ~(val & w1cmask));
  99. }
  100. static void amdvi_writel(AMDVIState *s, hwaddr addr, uint32_t val)
  101. {
  102. uint32_t romask = ldl_le_p(&s->romask[addr]);
  103. uint32_t w1cmask = ldl_le_p(&s->w1cmask[addr]);
  104. uint32_t oldval = ldl_le_p(&s->mmior[addr]);
  105. stl_le_p(&s->mmior[addr],
  106. ((oldval & romask) | (val & ~romask)) & ~(val & w1cmask));
  107. }
  108. static void amdvi_writeq(AMDVIState *s, hwaddr addr, uint64_t val)
  109. {
  110. uint64_t romask = ldq_le_p(&s->romask[addr]);
  111. uint64_t w1cmask = ldq_le_p(&s->w1cmask[addr]);
  112. uint32_t oldval = ldq_le_p(&s->mmior[addr]);
  113. stq_le_p(&s->mmior[addr],
  114. ((oldval & romask) | (val & ~romask)) & ~(val & w1cmask));
  115. }
  116. /* OR a 64-bit register with a 64-bit value */
  117. static bool amdvi_test_mask(AMDVIState *s, hwaddr addr, uint64_t val)
  118. {
  119. return amdvi_readq(s, addr) | val;
  120. }
  121. /* OR a 64-bit register with a 64-bit value storing result in the register */
  122. static void amdvi_assign_orq(AMDVIState *s, hwaddr addr, uint64_t val)
  123. {
  124. amdvi_writeq_raw(s, addr, amdvi_readq(s, addr) | val);
  125. }
  126. /* AND a 64-bit register with a 64-bit value storing result in the register */
  127. static void amdvi_assign_andq(AMDVIState *s, hwaddr addr, uint64_t val)
  128. {
  129. amdvi_writeq_raw(s, addr, amdvi_readq(s, addr) & val);
  130. }
  131. static void amdvi_generate_msi_interrupt(AMDVIState *s)
  132. {
  133. MSIMessage msg = {};
  134. MemTxAttrs attrs = {
  135. .requester_id = pci_requester_id(&s->pci.dev)
  136. };
  137. if (msi_enabled(&s->pci.dev)) {
  138. msg = msi_get_message(&s->pci.dev, 0);
  139. address_space_stl_le(&address_space_memory, msg.address, msg.data,
  140. attrs, NULL);
  141. }
  142. }
  143. static void amdvi_log_event(AMDVIState *s, uint64_t *evt)
  144. {
  145. /* event logging not enabled */
  146. if (!s->evtlog_enabled || amdvi_test_mask(s, AMDVI_MMIO_STATUS,
  147. AMDVI_MMIO_STATUS_EVT_OVF)) {
  148. return;
  149. }
  150. /* event log buffer full */
  151. if (s->evtlog_tail >= s->evtlog_len) {
  152. amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_EVT_OVF);
  153. /* generate interrupt */
  154. amdvi_generate_msi_interrupt(s);
  155. return;
  156. }
  157. if (dma_memory_write(&address_space_memory, s->evtlog + s->evtlog_tail,
  158. &evt, AMDVI_EVENT_LEN)) {
  159. trace_amdvi_evntlog_fail(s->evtlog, s->evtlog_tail);
  160. }
  161. s->evtlog_tail += AMDVI_EVENT_LEN;
  162. amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_COMP_INT);
  163. amdvi_generate_msi_interrupt(s);
  164. }
  165. static void amdvi_setevent_bits(uint64_t *buffer, uint64_t value, int start,
  166. int length)
  167. {
  168. int index = start / 64, bitpos = start % 64;
  169. uint64_t mask = MAKE_64BIT_MASK(start, length);
  170. buffer[index] &= ~mask;
  171. buffer[index] |= (value << bitpos) & mask;
  172. }
  173. /*
  174. * AMDVi event structure
  175. * 0:15 -> DeviceID
  176. * 55:63 -> event type + miscellaneous info
  177. * 63:127 -> related address
  178. */
  179. static void amdvi_encode_event(uint64_t *evt, uint16_t devid, uint64_t addr,
  180. uint16_t info)
  181. {
  182. amdvi_setevent_bits(evt, devid, 0, 16);
  183. amdvi_setevent_bits(evt, info, 55, 8);
  184. amdvi_setevent_bits(evt, addr, 63, 64);
  185. }
  186. /* log an error encountered during a page walk
  187. *
  188. * @addr: virtual address in translation request
  189. */
  190. static void amdvi_page_fault(AMDVIState *s, uint16_t devid,
  191. hwaddr addr, uint16_t info)
  192. {
  193. uint64_t evt[4];
  194. info |= AMDVI_EVENT_IOPF_I | AMDVI_EVENT_IOPF;
  195. amdvi_encode_event(evt, devid, addr, info);
  196. amdvi_log_event(s, evt);
  197. pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS,
  198. PCI_STATUS_SIG_TARGET_ABORT);
  199. }
  200. /*
  201. * log a master abort accessing device table
  202. * @devtab : address of device table entry
  203. * @info : error flags
  204. */
  205. static void amdvi_log_devtab_error(AMDVIState *s, uint16_t devid,
  206. hwaddr devtab, uint16_t info)
  207. {
  208. uint64_t evt[4];
  209. info |= AMDVI_EVENT_DEV_TAB_HW_ERROR;
  210. amdvi_encode_event(evt, devid, devtab, info);
  211. amdvi_log_event(s, evt);
  212. pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS,
  213. PCI_STATUS_SIG_TARGET_ABORT);
  214. }
  215. /* log an event trying to access command buffer
  216. * @addr : address that couldn't be accessed
  217. */
  218. static void amdvi_log_command_error(AMDVIState *s, hwaddr addr)
  219. {
  220. uint64_t evt[4], info = AMDVI_EVENT_COMMAND_HW_ERROR;
  221. amdvi_encode_event(evt, 0, addr, info);
  222. amdvi_log_event(s, evt);
  223. pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS,
  224. PCI_STATUS_SIG_TARGET_ABORT);
  225. }
  226. /* log an illegal comand event
  227. * @addr : address of illegal command
  228. */
  229. static void amdvi_log_illegalcom_error(AMDVIState *s, uint16_t info,
  230. hwaddr addr)
  231. {
  232. uint64_t evt[4];
  233. info |= AMDVI_EVENT_ILLEGAL_COMMAND_ERROR;
  234. amdvi_encode_event(evt, 0, addr, info);
  235. amdvi_log_event(s, evt);
  236. }
  237. /* log an error accessing device table
  238. *
  239. * @devid : device owning the table entry
  240. * @devtab : address of device table entry
  241. * @info : error flags
  242. */
  243. static void amdvi_log_illegaldevtab_error(AMDVIState *s, uint16_t devid,
  244. hwaddr addr, uint16_t info)
  245. {
  246. uint64_t evt[4];
  247. info |= AMDVI_EVENT_ILLEGAL_DEVTAB_ENTRY;
  248. amdvi_encode_event(evt, devid, addr, info);
  249. amdvi_log_event(s, evt);
  250. }
  251. /* log an error accessing a PTE entry
  252. * @addr : address that couldn't be accessed
  253. */
  254. static void amdvi_log_pagetab_error(AMDVIState *s, uint16_t devid,
  255. hwaddr addr, uint16_t info)
  256. {
  257. uint64_t evt[4];
  258. info |= AMDVI_EVENT_PAGE_TAB_HW_ERROR;
  259. amdvi_encode_event(evt, devid, addr, info);
  260. amdvi_log_event(s, evt);
  261. pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS,
  262. PCI_STATUS_SIG_TARGET_ABORT);
  263. }
  264. static gboolean amdvi_uint64_equal(gconstpointer v1, gconstpointer v2)
  265. {
  266. return *((const uint64_t *)v1) == *((const uint64_t *)v2);
  267. }
  268. static guint amdvi_uint64_hash(gconstpointer v)
  269. {
  270. return (guint)*(const uint64_t *)v;
  271. }
  272. static AMDVIIOTLBEntry *amdvi_iotlb_lookup(AMDVIState *s, hwaddr addr,
  273. uint64_t devid)
  274. {
  275. uint64_t key = (addr >> AMDVI_PAGE_SHIFT_4K) |
  276. ((uint64_t)(devid) << AMDVI_DEVID_SHIFT);
  277. return g_hash_table_lookup(s->iotlb, &key);
  278. }
  279. static void amdvi_iotlb_reset(AMDVIState *s)
  280. {
  281. assert(s->iotlb);
  282. trace_amdvi_iotlb_reset();
  283. g_hash_table_remove_all(s->iotlb);
  284. }
  285. static gboolean amdvi_iotlb_remove_by_devid(gpointer key, gpointer value,
  286. gpointer user_data)
  287. {
  288. AMDVIIOTLBEntry *entry = (AMDVIIOTLBEntry *)value;
  289. uint16_t devid = *(uint16_t *)user_data;
  290. return entry->devid == devid;
  291. }
  292. static void amdvi_iotlb_remove_page(AMDVIState *s, hwaddr addr,
  293. uint64_t devid)
  294. {
  295. uint64_t key = (addr >> AMDVI_PAGE_SHIFT_4K) |
  296. ((uint64_t)(devid) << AMDVI_DEVID_SHIFT);
  297. g_hash_table_remove(s->iotlb, &key);
  298. }
  299. static void amdvi_update_iotlb(AMDVIState *s, uint16_t devid,
  300. uint64_t gpa, IOMMUTLBEntry to_cache,
  301. uint16_t domid)
  302. {
  303. AMDVIIOTLBEntry *entry = g_new(AMDVIIOTLBEntry, 1);
  304. uint64_t *key = g_new(uint64_t, 1);
  305. uint64_t gfn = gpa >> AMDVI_PAGE_SHIFT_4K;
  306. /* don't cache erroneous translations */
  307. if (to_cache.perm != IOMMU_NONE) {
  308. trace_amdvi_cache_update(domid, PCI_BUS_NUM(devid), PCI_SLOT(devid),
  309. PCI_FUNC(devid), gpa, to_cache.translated_addr);
  310. if (g_hash_table_size(s->iotlb) >= AMDVI_IOTLB_MAX_SIZE) {
  311. amdvi_iotlb_reset(s);
  312. }
  313. entry->domid = domid;
  314. entry->perms = to_cache.perm;
  315. entry->translated_addr = to_cache.translated_addr;
  316. entry->page_mask = to_cache.addr_mask;
  317. *key = gfn | ((uint64_t)(devid) << AMDVI_DEVID_SHIFT);
  318. g_hash_table_replace(s->iotlb, key, entry);
  319. }
  320. }
  321. static void amdvi_completion_wait(AMDVIState *s, uint64_t *cmd)
  322. {
  323. /* pad the last 3 bits */
  324. hwaddr addr = cpu_to_le64(extract64(cmd[0], 3, 49)) << 3;
  325. uint64_t data = cpu_to_le64(cmd[1]);
  326. if (extract64(cmd[0], 51, 8)) {
  327. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  328. s->cmdbuf + s->cmdbuf_head);
  329. }
  330. if (extract64(cmd[0], 0, 1)) {
  331. if (dma_memory_write(&address_space_memory, addr, &data,
  332. AMDVI_COMPLETION_DATA_SIZE)) {
  333. trace_amdvi_completion_wait_fail(addr);
  334. }
  335. }
  336. /* set completion interrupt */
  337. if (extract64(cmd[0], 1, 1)) {
  338. amdvi_test_mask(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_COMP_INT);
  339. /* generate interrupt */
  340. amdvi_generate_msi_interrupt(s);
  341. }
  342. trace_amdvi_completion_wait(addr, data);
  343. }
  344. /* log error without aborting since linux seems to be using reserved bits */
  345. static void amdvi_inval_devtab_entry(AMDVIState *s, uint64_t *cmd)
  346. {
  347. uint16_t devid = cpu_to_le16((uint16_t)extract64(cmd[0], 0, 16));
  348. /* This command should invalidate internal caches of which there isn't */
  349. if (extract64(cmd[0], 15, 16) || cmd[1]) {
  350. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  351. s->cmdbuf + s->cmdbuf_head);
  352. }
  353. trace_amdvi_devtab_inval(PCI_BUS_NUM(devid), PCI_SLOT(devid),
  354. PCI_FUNC(devid));
  355. }
  356. static void amdvi_complete_ppr(AMDVIState *s, uint64_t *cmd)
  357. {
  358. if (extract64(cmd[0], 15, 16) || extract64(cmd[0], 19, 8) ||
  359. extract64(cmd[1], 0, 2) || extract64(cmd[1], 3, 29)
  360. || extract64(cmd[1], 47, 16)) {
  361. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  362. s->cmdbuf + s->cmdbuf_head);
  363. }
  364. trace_amdvi_ppr_exec();
  365. }
  366. static void amdvi_inval_all(AMDVIState *s, uint64_t *cmd)
  367. {
  368. if (extract64(cmd[0], 0, 60) || cmd[1]) {
  369. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  370. s->cmdbuf + s->cmdbuf_head);
  371. }
  372. amdvi_iotlb_reset(s);
  373. trace_amdvi_all_inval();
  374. }
  375. static gboolean amdvi_iotlb_remove_by_domid(gpointer key, gpointer value,
  376. gpointer user_data)
  377. {
  378. AMDVIIOTLBEntry *entry = (AMDVIIOTLBEntry *)value;
  379. uint16_t domid = *(uint16_t *)user_data;
  380. return entry->domid == domid;
  381. }
  382. /* we don't have devid - we can't remove pages by address */
  383. static void amdvi_inval_pages(AMDVIState *s, uint64_t *cmd)
  384. {
  385. uint16_t domid = cpu_to_le16((uint16_t)extract64(cmd[0], 32, 16));
  386. if (extract64(cmd[0], 20, 12) || extract64(cmd[0], 16, 12) ||
  387. extract64(cmd[0], 3, 10)) {
  388. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  389. s->cmdbuf + s->cmdbuf_head);
  390. }
  391. g_hash_table_foreach_remove(s->iotlb, amdvi_iotlb_remove_by_domid,
  392. &domid);
  393. trace_amdvi_pages_inval(domid);
  394. }
  395. static void amdvi_prefetch_pages(AMDVIState *s, uint64_t *cmd)
  396. {
  397. if (extract64(cmd[0], 16, 8) || extract64(cmd[0], 20, 8) ||
  398. extract64(cmd[1], 1, 1) || extract64(cmd[1], 3, 1) ||
  399. extract64(cmd[1], 5, 7)) {
  400. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  401. s->cmdbuf + s->cmdbuf_head);
  402. }
  403. trace_amdvi_prefetch_pages();
  404. }
  405. static void amdvi_inval_inttable(AMDVIState *s, uint64_t *cmd)
  406. {
  407. if (extract64(cmd[0], 16, 16) || cmd[1]) {
  408. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  409. s->cmdbuf + s->cmdbuf_head);
  410. return;
  411. }
  412. trace_amdvi_intr_inval();
  413. }
  414. /* FIXME: Try to work with the specified size instead of all the pages
  415. * when the S bit is on
  416. */
  417. static void iommu_inval_iotlb(AMDVIState *s, uint64_t *cmd)
  418. {
  419. uint16_t devid = extract64(cmd[0], 0, 16);
  420. if (extract64(cmd[1], 1, 1) || extract64(cmd[1], 3, 9)) {
  421. amdvi_log_illegalcom_error(s, extract64(cmd[0], 60, 4),
  422. s->cmdbuf + s->cmdbuf_head);
  423. return;
  424. }
  425. if (extract64(cmd[1], 0, 1)) {
  426. g_hash_table_foreach_remove(s->iotlb, amdvi_iotlb_remove_by_devid,
  427. &devid);
  428. } else {
  429. amdvi_iotlb_remove_page(s, cpu_to_le64(extract64(cmd[1], 12, 52)) << 12,
  430. cpu_to_le16(extract64(cmd[1], 0, 16)));
  431. }
  432. trace_amdvi_iotlb_inval();
  433. }
  434. /* not honouring reserved bits is regarded as an illegal command */
  435. static void amdvi_cmdbuf_exec(AMDVIState *s)
  436. {
  437. uint64_t cmd[2];
  438. if (dma_memory_read(&address_space_memory, s->cmdbuf + s->cmdbuf_head,
  439. cmd, AMDVI_COMMAND_SIZE)) {
  440. trace_amdvi_command_read_fail(s->cmdbuf, s->cmdbuf_head);
  441. amdvi_log_command_error(s, s->cmdbuf + s->cmdbuf_head);
  442. return;
  443. }
  444. switch (extract64(cmd[0], 60, 4)) {
  445. case AMDVI_CMD_COMPLETION_WAIT:
  446. amdvi_completion_wait(s, cmd);
  447. break;
  448. case AMDVI_CMD_INVAL_DEVTAB_ENTRY:
  449. amdvi_inval_devtab_entry(s, cmd);
  450. break;
  451. case AMDVI_CMD_INVAL_AMDVI_PAGES:
  452. amdvi_inval_pages(s, cmd);
  453. break;
  454. case AMDVI_CMD_INVAL_IOTLB_PAGES:
  455. iommu_inval_iotlb(s, cmd);
  456. break;
  457. case AMDVI_CMD_INVAL_INTR_TABLE:
  458. amdvi_inval_inttable(s, cmd);
  459. break;
  460. case AMDVI_CMD_PREFETCH_AMDVI_PAGES:
  461. amdvi_prefetch_pages(s, cmd);
  462. break;
  463. case AMDVI_CMD_COMPLETE_PPR_REQUEST:
  464. amdvi_complete_ppr(s, cmd);
  465. break;
  466. case AMDVI_CMD_INVAL_AMDVI_ALL:
  467. amdvi_inval_all(s, cmd);
  468. break;
  469. default:
  470. trace_amdvi_unhandled_command(extract64(cmd[1], 60, 4));
  471. /* log illegal command */
  472. amdvi_log_illegalcom_error(s, extract64(cmd[1], 60, 4),
  473. s->cmdbuf + s->cmdbuf_head);
  474. }
  475. }
  476. static void amdvi_cmdbuf_run(AMDVIState *s)
  477. {
  478. if (!s->cmdbuf_enabled) {
  479. trace_amdvi_command_error(amdvi_readq(s, AMDVI_MMIO_CONTROL));
  480. return;
  481. }
  482. /* check if there is work to do. */
  483. while (s->cmdbuf_head != s->cmdbuf_tail) {
  484. trace_amdvi_command_exec(s->cmdbuf_head, s->cmdbuf_tail, s->cmdbuf);
  485. amdvi_cmdbuf_exec(s);
  486. s->cmdbuf_head += AMDVI_COMMAND_SIZE;
  487. amdvi_writeq_raw(s, s->cmdbuf_head, AMDVI_MMIO_COMMAND_HEAD);
  488. /* wrap head pointer */
  489. if (s->cmdbuf_head >= s->cmdbuf_len * AMDVI_COMMAND_SIZE) {
  490. s->cmdbuf_head = 0;
  491. }
  492. }
  493. }
  494. static void amdvi_mmio_trace(hwaddr addr, unsigned size)
  495. {
  496. uint8_t index = (addr & ~0x2000) / 8;
  497. if ((addr & 0x2000)) {
  498. /* high table */
  499. index = index >= AMDVI_MMIO_REGS_HIGH ? AMDVI_MMIO_REGS_HIGH : index;
  500. trace_amdvi_mmio_read(amdvi_mmio_high[index], addr, size, addr & ~0x07);
  501. } else {
  502. index = index >= AMDVI_MMIO_REGS_LOW ? AMDVI_MMIO_REGS_LOW : index;
  503. trace_amdvi_mmio_read(amdvi_mmio_low[index], addr, size, addr & ~0x07);
  504. }
  505. }
  506. static uint64_t amdvi_mmio_read(void *opaque, hwaddr addr, unsigned size)
  507. {
  508. AMDVIState *s = opaque;
  509. uint64_t val = -1;
  510. if (addr + size > AMDVI_MMIO_SIZE) {
  511. trace_amdvi_mmio_read_invalid(AMDVI_MMIO_SIZE, addr, size);
  512. return (uint64_t)-1;
  513. }
  514. if (size == 2) {
  515. val = amdvi_readw(s, addr);
  516. } else if (size == 4) {
  517. val = amdvi_readl(s, addr);
  518. } else if (size == 8) {
  519. val = amdvi_readq(s, addr);
  520. }
  521. amdvi_mmio_trace(addr, size);
  522. return val;
  523. }
  524. static void amdvi_handle_control_write(AMDVIState *s)
  525. {
  526. unsigned long control = amdvi_readq(s, AMDVI_MMIO_CONTROL);
  527. s->enabled = !!(control & AMDVI_MMIO_CONTROL_AMDVIEN);
  528. s->ats_enabled = !!(control & AMDVI_MMIO_CONTROL_HTTUNEN);
  529. s->evtlog_enabled = s->enabled && !!(control &
  530. AMDVI_MMIO_CONTROL_EVENTLOGEN);
  531. s->evtlog_intr = !!(control & AMDVI_MMIO_CONTROL_EVENTINTEN);
  532. s->completion_wait_intr = !!(control & AMDVI_MMIO_CONTROL_COMWAITINTEN);
  533. s->cmdbuf_enabled = s->enabled && !!(control &
  534. AMDVI_MMIO_CONTROL_CMDBUFLEN);
  535. /* update the flags depending on the control register */
  536. if (s->cmdbuf_enabled) {
  537. amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_CMDBUF_RUN);
  538. } else {
  539. amdvi_assign_andq(s, AMDVI_MMIO_STATUS, ~AMDVI_MMIO_STATUS_CMDBUF_RUN);
  540. }
  541. if (s->evtlog_enabled) {
  542. amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_EVT_RUN);
  543. } else {
  544. amdvi_assign_andq(s, AMDVI_MMIO_STATUS, ~AMDVI_MMIO_STATUS_EVT_RUN);
  545. }
  546. trace_amdvi_control_status(control);
  547. amdvi_cmdbuf_run(s);
  548. }
  549. static inline void amdvi_handle_devtab_write(AMDVIState *s)
  550. {
  551. uint64_t val = amdvi_readq(s, AMDVI_MMIO_DEVICE_TABLE);
  552. s->devtab = (val & AMDVI_MMIO_DEVTAB_BASE_MASK);
  553. /* set device table length */
  554. s->devtab_len = ((val & AMDVI_MMIO_DEVTAB_SIZE_MASK) + 1 *
  555. (AMDVI_MMIO_DEVTAB_SIZE_UNIT /
  556. AMDVI_MMIO_DEVTAB_ENTRY_SIZE));
  557. }
  558. static inline void amdvi_handle_cmdhead_write(AMDVIState *s)
  559. {
  560. s->cmdbuf_head = amdvi_readq(s, AMDVI_MMIO_COMMAND_HEAD)
  561. & AMDVI_MMIO_CMDBUF_HEAD_MASK;
  562. amdvi_cmdbuf_run(s);
  563. }
  564. static inline void amdvi_handle_cmdbase_write(AMDVIState *s)
  565. {
  566. s->cmdbuf = amdvi_readq(s, AMDVI_MMIO_COMMAND_BASE)
  567. & AMDVI_MMIO_CMDBUF_BASE_MASK;
  568. s->cmdbuf_len = 1UL << (amdvi_readq(s, AMDVI_MMIO_CMDBUF_SIZE_BYTE)
  569. & AMDVI_MMIO_CMDBUF_SIZE_MASK);
  570. s->cmdbuf_head = s->cmdbuf_tail = 0;
  571. }
  572. static inline void amdvi_handle_cmdtail_write(AMDVIState *s)
  573. {
  574. s->cmdbuf_tail = amdvi_readq(s, AMDVI_MMIO_COMMAND_TAIL)
  575. & AMDVI_MMIO_CMDBUF_TAIL_MASK;
  576. amdvi_cmdbuf_run(s);
  577. }
  578. static inline void amdvi_handle_excllim_write(AMDVIState *s)
  579. {
  580. uint64_t val = amdvi_readq(s, AMDVI_MMIO_EXCL_LIMIT);
  581. s->excl_limit = (val & AMDVI_MMIO_EXCL_LIMIT_MASK) |
  582. AMDVI_MMIO_EXCL_LIMIT_LOW;
  583. }
  584. static inline void amdvi_handle_evtbase_write(AMDVIState *s)
  585. {
  586. uint64_t val = amdvi_readq(s, AMDVI_MMIO_EVENT_BASE);
  587. s->evtlog = val & AMDVI_MMIO_EVTLOG_BASE_MASK;
  588. s->evtlog_len = 1UL << (amdvi_readq(s, AMDVI_MMIO_EVTLOG_SIZE_BYTE)
  589. & AMDVI_MMIO_EVTLOG_SIZE_MASK);
  590. }
  591. static inline void amdvi_handle_evttail_write(AMDVIState *s)
  592. {
  593. uint64_t val = amdvi_readq(s, AMDVI_MMIO_EVENT_TAIL);
  594. s->evtlog_tail = val & AMDVI_MMIO_EVTLOG_TAIL_MASK;
  595. }
  596. static inline void amdvi_handle_evthead_write(AMDVIState *s)
  597. {
  598. uint64_t val = amdvi_readq(s, AMDVI_MMIO_EVENT_HEAD);
  599. s->evtlog_head = val & AMDVI_MMIO_EVTLOG_HEAD_MASK;
  600. }
  601. static inline void amdvi_handle_pprbase_write(AMDVIState *s)
  602. {
  603. uint64_t val = amdvi_readq(s, AMDVI_MMIO_PPR_BASE);
  604. s->ppr_log = val & AMDVI_MMIO_PPRLOG_BASE_MASK;
  605. s->pprlog_len = 1UL << (amdvi_readq(s, AMDVI_MMIO_PPRLOG_SIZE_BYTE)
  606. & AMDVI_MMIO_PPRLOG_SIZE_MASK);
  607. }
  608. static inline void amdvi_handle_pprhead_write(AMDVIState *s)
  609. {
  610. uint64_t val = amdvi_readq(s, AMDVI_MMIO_PPR_HEAD);
  611. s->pprlog_head = val & AMDVI_MMIO_PPRLOG_HEAD_MASK;
  612. }
  613. static inline void amdvi_handle_pprtail_write(AMDVIState *s)
  614. {
  615. uint64_t val = amdvi_readq(s, AMDVI_MMIO_PPR_TAIL);
  616. s->pprlog_tail = val & AMDVI_MMIO_PPRLOG_TAIL_MASK;
  617. }
  618. /* FIXME: something might go wrong if System Software writes in chunks
  619. * of one byte but linux writes in chunks of 4 bytes so currently it
  620. * works correctly with linux but will definitely be busted if software
  621. * reads/writes 8 bytes
  622. */
  623. static void amdvi_mmio_reg_write(AMDVIState *s, unsigned size, uint64_t val,
  624. hwaddr addr)
  625. {
  626. if (size == 2) {
  627. amdvi_writew(s, addr, val);
  628. } else if (size == 4) {
  629. amdvi_writel(s, addr, val);
  630. } else if (size == 8) {
  631. amdvi_writeq(s, addr, val);
  632. }
  633. }
  634. static void amdvi_mmio_write(void *opaque, hwaddr addr, uint64_t val,
  635. unsigned size)
  636. {
  637. AMDVIState *s = opaque;
  638. unsigned long offset = addr & 0x07;
  639. if (addr + size > AMDVI_MMIO_SIZE) {
  640. trace_amdvi_mmio_write("error: addr outside region: max ",
  641. (uint64_t)AMDVI_MMIO_SIZE, size, val, offset);
  642. return;
  643. }
  644. amdvi_mmio_trace(addr, size);
  645. switch (addr & ~0x07) {
  646. case AMDVI_MMIO_CONTROL:
  647. amdvi_mmio_reg_write(s, size, val, addr);
  648. amdvi_handle_control_write(s);
  649. break;
  650. case AMDVI_MMIO_DEVICE_TABLE:
  651. amdvi_mmio_reg_write(s, size, val, addr);
  652. /* set device table address
  653. * This also suffers from inability to tell whether software
  654. * is done writing
  655. */
  656. if (offset || (size == 8)) {
  657. amdvi_handle_devtab_write(s);
  658. }
  659. break;
  660. case AMDVI_MMIO_COMMAND_HEAD:
  661. amdvi_mmio_reg_write(s, size, val, addr);
  662. amdvi_handle_cmdhead_write(s);
  663. break;
  664. case AMDVI_MMIO_COMMAND_BASE:
  665. amdvi_mmio_reg_write(s, size, val, addr);
  666. /* FIXME - make sure System Software has finished writing incase
  667. * it writes in chucks less than 8 bytes in a robust way.As for
  668. * now, this hacks works for the linux driver
  669. */
  670. if (offset || (size == 8)) {
  671. amdvi_handle_cmdbase_write(s);
  672. }
  673. break;
  674. case AMDVI_MMIO_COMMAND_TAIL:
  675. amdvi_mmio_reg_write(s, size, val, addr);
  676. amdvi_handle_cmdtail_write(s);
  677. break;
  678. case AMDVI_MMIO_EVENT_BASE:
  679. amdvi_mmio_reg_write(s, size, val, addr);
  680. amdvi_handle_evtbase_write(s);
  681. break;
  682. case AMDVI_MMIO_EVENT_HEAD:
  683. amdvi_mmio_reg_write(s, size, val, addr);
  684. amdvi_handle_evthead_write(s);
  685. break;
  686. case AMDVI_MMIO_EVENT_TAIL:
  687. amdvi_mmio_reg_write(s, size, val, addr);
  688. amdvi_handle_evttail_write(s);
  689. break;
  690. case AMDVI_MMIO_EXCL_LIMIT:
  691. amdvi_mmio_reg_write(s, size, val, addr);
  692. amdvi_handle_excllim_write(s);
  693. break;
  694. /* PPR log base - unused for now */
  695. case AMDVI_MMIO_PPR_BASE:
  696. amdvi_mmio_reg_write(s, size, val, addr);
  697. amdvi_handle_pprbase_write(s);
  698. break;
  699. /* PPR log head - also unused for now */
  700. case AMDVI_MMIO_PPR_HEAD:
  701. amdvi_mmio_reg_write(s, size, val, addr);
  702. amdvi_handle_pprhead_write(s);
  703. break;
  704. /* PPR log tail - unused for now */
  705. case AMDVI_MMIO_PPR_TAIL:
  706. amdvi_mmio_reg_write(s, size, val, addr);
  707. amdvi_handle_pprtail_write(s);
  708. break;
  709. }
  710. }
  711. static inline uint64_t amdvi_get_perms(uint64_t entry)
  712. {
  713. return (entry & (AMDVI_DEV_PERM_READ | AMDVI_DEV_PERM_WRITE)) >>
  714. AMDVI_DEV_PERM_SHIFT;
  715. }
  716. /* a valid entry should have V = 1 and reserved bits honoured */
  717. static bool amdvi_validate_dte(AMDVIState *s, uint16_t devid,
  718. uint64_t *dte)
  719. {
  720. if ((dte[0] & AMDVI_DTE_LOWER_QUAD_RESERVED)
  721. || (dte[1] & AMDVI_DTE_MIDDLE_QUAD_RESERVED)
  722. || (dte[2] & AMDVI_DTE_UPPER_QUAD_RESERVED) || dte[3]) {
  723. amdvi_log_illegaldevtab_error(s, devid,
  724. s->devtab +
  725. devid * AMDVI_DEVTAB_ENTRY_SIZE, 0);
  726. return false;
  727. }
  728. return dte[0] & AMDVI_DEV_VALID;
  729. }
  730. /* get a device table entry given the devid */
  731. static bool amdvi_get_dte(AMDVIState *s, int devid, uint64_t *entry)
  732. {
  733. uint32_t offset = devid * AMDVI_DEVTAB_ENTRY_SIZE;
  734. if (dma_memory_read(&address_space_memory, s->devtab + offset, entry,
  735. AMDVI_DEVTAB_ENTRY_SIZE)) {
  736. trace_amdvi_dte_get_fail(s->devtab, offset);
  737. /* log error accessing dte */
  738. amdvi_log_devtab_error(s, devid, s->devtab + offset, 0);
  739. return false;
  740. }
  741. *entry = le64_to_cpu(*entry);
  742. if (!amdvi_validate_dte(s, devid, entry)) {
  743. trace_amdvi_invalid_dte(entry[0]);
  744. return false;
  745. }
  746. return true;
  747. }
  748. /* get pte translation mode */
  749. static inline uint8_t get_pte_translation_mode(uint64_t pte)
  750. {
  751. return (pte >> AMDVI_DEV_MODE_RSHIFT) & AMDVI_DEV_MODE_MASK;
  752. }
  753. static inline uint64_t pte_override_page_mask(uint64_t pte)
  754. {
  755. uint8_t page_mask = 12;
  756. uint64_t addr = (pte & AMDVI_DEV_PT_ROOT_MASK) ^ AMDVI_DEV_PT_ROOT_MASK;
  757. /* find the first zero bit */
  758. while (addr & 1) {
  759. page_mask++;
  760. addr = addr >> 1;
  761. }
  762. return ~((1ULL << page_mask) - 1);
  763. }
  764. static inline uint64_t pte_get_page_mask(uint64_t oldlevel)
  765. {
  766. return ~((1UL << ((oldlevel * 9) + 3)) - 1);
  767. }
  768. static inline uint64_t amdvi_get_pte_entry(AMDVIState *s, uint64_t pte_addr,
  769. uint16_t devid)
  770. {
  771. uint64_t pte;
  772. if (dma_memory_read(&address_space_memory, pte_addr, &pte, sizeof(pte))) {
  773. trace_amdvi_get_pte_hwerror(pte_addr);
  774. amdvi_log_pagetab_error(s, devid, pte_addr, 0);
  775. pte = 0;
  776. return pte;
  777. }
  778. pte = le64_to_cpu(pte);
  779. return pte;
  780. }
  781. static void amdvi_page_walk(AMDVIAddressSpace *as, uint64_t *dte,
  782. IOMMUTLBEntry *ret, unsigned perms,
  783. hwaddr addr)
  784. {
  785. unsigned level, present, pte_perms, oldlevel;
  786. uint64_t pte = dte[0], pte_addr, page_mask;
  787. /* make sure the DTE has TV = 1 */
  788. if (pte & AMDVI_DEV_TRANSLATION_VALID) {
  789. level = get_pte_translation_mode(pte);
  790. if (level >= 7) {
  791. trace_amdvi_mode_invalid(level, addr);
  792. return;
  793. }
  794. if (level == 0) {
  795. goto no_remap;
  796. }
  797. /* we are at the leaf page table or page table encodes a huge page */
  798. while (level > 0) {
  799. pte_perms = amdvi_get_perms(pte);
  800. present = pte & 1;
  801. if (!present || perms != (perms & pte_perms)) {
  802. amdvi_page_fault(as->iommu_state, as->devfn, addr, perms);
  803. trace_amdvi_page_fault(addr);
  804. return;
  805. }
  806. /* go to the next lower level */
  807. pte_addr = pte & AMDVI_DEV_PT_ROOT_MASK;
  808. /* add offset and load pte */
  809. pte_addr += ((addr >> (3 + 9 * level)) & 0x1FF) << 3;
  810. pte = amdvi_get_pte_entry(as->iommu_state, pte_addr, as->devfn);
  811. if (!pte) {
  812. return;
  813. }
  814. oldlevel = level;
  815. level = get_pte_translation_mode(pte);
  816. if (level == 0x7) {
  817. break;
  818. }
  819. }
  820. if (level == 0x7) {
  821. page_mask = pte_override_page_mask(pte);
  822. } else {
  823. page_mask = pte_get_page_mask(oldlevel);
  824. }
  825. /* get access permissions from pte */
  826. ret->iova = addr & page_mask;
  827. ret->translated_addr = (pte & AMDVI_DEV_PT_ROOT_MASK) & page_mask;
  828. ret->addr_mask = ~page_mask;
  829. ret->perm = amdvi_get_perms(pte);
  830. return;
  831. }
  832. no_remap:
  833. ret->iova = addr & AMDVI_PAGE_MASK_4K;
  834. ret->translated_addr = addr & AMDVI_PAGE_MASK_4K;
  835. ret->addr_mask = ~AMDVI_PAGE_MASK_4K;
  836. ret->perm = amdvi_get_perms(pte);
  837. }
  838. static void amdvi_do_translate(AMDVIAddressSpace *as, hwaddr addr,
  839. bool is_write, IOMMUTLBEntry *ret)
  840. {
  841. AMDVIState *s = as->iommu_state;
  842. uint16_t devid = PCI_BUILD_BDF(as->bus_num, as->devfn);
  843. AMDVIIOTLBEntry *iotlb_entry = amdvi_iotlb_lookup(s, addr, devid);
  844. uint64_t entry[4];
  845. if (iotlb_entry) {
  846. trace_amdvi_iotlb_hit(PCI_BUS_NUM(devid), PCI_SLOT(devid),
  847. PCI_FUNC(devid), addr, iotlb_entry->translated_addr);
  848. ret->iova = addr & ~iotlb_entry->page_mask;
  849. ret->translated_addr = iotlb_entry->translated_addr;
  850. ret->addr_mask = iotlb_entry->page_mask;
  851. ret->perm = iotlb_entry->perms;
  852. return;
  853. }
  854. /* devices with V = 0 are not translated */
  855. if (!amdvi_get_dte(s, devid, entry)) {
  856. goto out;
  857. }
  858. amdvi_page_walk(as, entry, ret,
  859. is_write ? AMDVI_PERM_WRITE : AMDVI_PERM_READ, addr);
  860. amdvi_update_iotlb(s, devid, addr, *ret,
  861. entry[1] & AMDVI_DEV_DOMID_ID_MASK);
  862. return;
  863. out:
  864. ret->iova = addr & AMDVI_PAGE_MASK_4K;
  865. ret->translated_addr = addr & AMDVI_PAGE_MASK_4K;
  866. ret->addr_mask = ~AMDVI_PAGE_MASK_4K;
  867. ret->perm = IOMMU_RW;
  868. }
  869. static inline bool amdvi_is_interrupt_addr(hwaddr addr)
  870. {
  871. return addr >= AMDVI_INT_ADDR_FIRST && addr <= AMDVI_INT_ADDR_LAST;
  872. }
  873. static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
  874. IOMMUAccessFlags flag, int iommu_idx)
  875. {
  876. AMDVIAddressSpace *as = container_of(iommu, AMDVIAddressSpace, iommu);
  877. AMDVIState *s = as->iommu_state;
  878. IOMMUTLBEntry ret = {
  879. .target_as = &address_space_memory,
  880. .iova = addr,
  881. .translated_addr = 0,
  882. .addr_mask = ~(hwaddr)0,
  883. .perm = IOMMU_NONE
  884. };
  885. if (!s->enabled) {
  886. /* AMDVI disabled - corresponds to iommu=off not
  887. * failure to provide any parameter
  888. */
  889. ret.iova = addr & AMDVI_PAGE_MASK_4K;
  890. ret.translated_addr = addr & AMDVI_PAGE_MASK_4K;
  891. ret.addr_mask = ~AMDVI_PAGE_MASK_4K;
  892. ret.perm = IOMMU_RW;
  893. return ret;
  894. } else if (amdvi_is_interrupt_addr(addr)) {
  895. ret.iova = addr & AMDVI_PAGE_MASK_4K;
  896. ret.translated_addr = addr & AMDVI_PAGE_MASK_4K;
  897. ret.addr_mask = ~AMDVI_PAGE_MASK_4K;
  898. ret.perm = IOMMU_WO;
  899. return ret;
  900. }
  901. amdvi_do_translate(as, addr, flag & IOMMU_WO, &ret);
  902. trace_amdvi_translation_result(as->bus_num, PCI_SLOT(as->devfn),
  903. PCI_FUNC(as->devfn), addr, ret.translated_addr);
  904. return ret;
  905. }
  906. static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
  907. {
  908. AMDVIState *s = opaque;
  909. AMDVIAddressSpace **iommu_as;
  910. int bus_num = pci_bus_num(bus);
  911. iommu_as = s->address_spaces[bus_num];
  912. /* allocate memory during the first run */
  913. if (!iommu_as) {
  914. iommu_as = g_malloc0(sizeof(AMDVIAddressSpace *) * PCI_DEVFN_MAX);
  915. s->address_spaces[bus_num] = iommu_as;
  916. }
  917. /* set up AMD-Vi region */
  918. if (!iommu_as[devfn]) {
  919. iommu_as[devfn] = g_malloc0(sizeof(AMDVIAddressSpace));
  920. iommu_as[devfn]->bus_num = (uint8_t)bus_num;
  921. iommu_as[devfn]->devfn = (uint8_t)devfn;
  922. iommu_as[devfn]->iommu_state = s;
  923. memory_region_init_iommu(&iommu_as[devfn]->iommu,
  924. sizeof(iommu_as[devfn]->iommu),
  925. TYPE_AMD_IOMMU_MEMORY_REGION,
  926. OBJECT(s),
  927. "amd-iommu", UINT64_MAX);
  928. address_space_init(&iommu_as[devfn]->as,
  929. MEMORY_REGION(&iommu_as[devfn]->iommu),
  930. "amd-iommu");
  931. }
  932. return &iommu_as[devfn]->as;
  933. }
  934. static const MemoryRegionOps mmio_mem_ops = {
  935. .read = amdvi_mmio_read,
  936. .write = amdvi_mmio_write,
  937. .endianness = DEVICE_LITTLE_ENDIAN,
  938. .impl = {
  939. .min_access_size = 1,
  940. .max_access_size = 8,
  941. .unaligned = false,
  942. },
  943. .valid = {
  944. .min_access_size = 1,
  945. .max_access_size = 8,
  946. }
  947. };
  948. static void amdvi_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
  949. IOMMUNotifierFlag old,
  950. IOMMUNotifierFlag new)
  951. {
  952. AMDVIAddressSpace *as = container_of(iommu, AMDVIAddressSpace, iommu);
  953. if (new & IOMMU_NOTIFIER_MAP) {
  954. error_report("device %02x.%02x.%x requires iommu notifier which is not "
  955. "currently supported", as->bus_num, PCI_SLOT(as->devfn),
  956. PCI_FUNC(as->devfn));
  957. exit(1);
  958. }
  959. }
  960. static void amdvi_init(AMDVIState *s)
  961. {
  962. amdvi_iotlb_reset(s);
  963. s->devtab_len = 0;
  964. s->cmdbuf_len = 0;
  965. s->cmdbuf_head = 0;
  966. s->cmdbuf_tail = 0;
  967. s->evtlog_head = 0;
  968. s->evtlog_tail = 0;
  969. s->excl_enabled = false;
  970. s->excl_allow = false;
  971. s->mmio_enabled = false;
  972. s->enabled = false;
  973. s->ats_enabled = false;
  974. s->cmdbuf_enabled = false;
  975. /* reset MMIO */
  976. memset(s->mmior, 0, AMDVI_MMIO_SIZE);
  977. amdvi_set_quad(s, AMDVI_MMIO_EXT_FEATURES, AMDVI_EXT_FEATURES,
  978. 0xffffffffffffffef, 0);
  979. amdvi_set_quad(s, AMDVI_MMIO_STATUS, 0, 0x98, 0x67);
  980. /* reset device ident */
  981. pci_config_set_vendor_id(s->pci.dev.config, PCI_VENDOR_ID_AMD);
  982. pci_config_set_prog_interface(s->pci.dev.config, 00);
  983. pci_config_set_device_id(s->pci.dev.config, s->devid);
  984. pci_config_set_class(s->pci.dev.config, 0x0806);
  985. /* reset AMDVI specific capabilities, all r/o */
  986. pci_set_long(s->pci.dev.config + s->capab_offset, AMDVI_CAPAB_FEATURES);
  987. pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_BAR_LOW,
  988. s->mmio.addr & ~(0xffff0000));
  989. pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_BAR_HIGH,
  990. (s->mmio.addr & ~(0xffff)) >> 16);
  991. pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_RANGE,
  992. 0xff000000);
  993. pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_MISC, 0);
  994. pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_MISC,
  995. AMDVI_MAX_PH_ADDR | AMDVI_MAX_GVA_ADDR | AMDVI_MAX_VA_ADDR);
  996. }
  997. static void amdvi_reset(DeviceState *dev)
  998. {
  999. AMDVIState *s = AMD_IOMMU_DEVICE(dev);
  1000. msi_reset(&s->pci.dev);
  1001. amdvi_init(s);
  1002. }
  1003. static void amdvi_realize(DeviceState *dev, Error **err)
  1004. {
  1005. int ret = 0;
  1006. AMDVIState *s = AMD_IOMMU_DEVICE(dev);
  1007. X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
  1008. MachineState *ms = MACHINE(qdev_get_machine());
  1009. PCMachineState *pcms = PC_MACHINE(ms);
  1010. PCIBus *bus = pcms->bus;
  1011. s->iotlb = g_hash_table_new_full(amdvi_uint64_hash,
  1012. amdvi_uint64_equal, g_free, g_free);
  1013. /* This device should take care of IOMMU PCI properties */
  1014. x86_iommu->type = TYPE_AMD;
  1015. qdev_set_parent_bus(DEVICE(&s->pci), &bus->qbus);
  1016. object_property_set_bool(OBJECT(&s->pci), true, "realized", err);
  1017. ret = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0,
  1018. AMDVI_CAPAB_SIZE, err);
  1019. if (ret < 0) {
  1020. return;
  1021. }
  1022. s->capab_offset = ret;
  1023. ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0,
  1024. AMDVI_CAPAB_REG_SIZE, err);
  1025. if (ret < 0) {
  1026. return;
  1027. }
  1028. ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0,
  1029. AMDVI_CAPAB_REG_SIZE, err);
  1030. if (ret < 0) {
  1031. return;
  1032. }
  1033. /* set up MMIO */
  1034. memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio",
  1035. AMDVI_MMIO_SIZE);
  1036. sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio);
  1037. sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, AMDVI_BASE_ADDR);
  1038. pci_setup_iommu(bus, amdvi_host_dma_iommu, s);
  1039. s->devid = object_property_get_int(OBJECT(&s->pci), "addr", err);
  1040. msi_init(&s->pci.dev, 0, 1, true, false, err);
  1041. amdvi_init(s);
  1042. }
  1043. static const VMStateDescription vmstate_amdvi = {
  1044. .name = "amd-iommu",
  1045. .unmigratable = 1
  1046. };
  1047. static void amdvi_instance_init(Object *klass)
  1048. {
  1049. AMDVIState *s = AMD_IOMMU_DEVICE(klass);
  1050. object_initialize(&s->pci, sizeof(s->pci), TYPE_AMD_IOMMU_PCI);
  1051. }
  1052. static void amdvi_class_init(ObjectClass *klass, void* data)
  1053. {
  1054. DeviceClass *dc = DEVICE_CLASS(klass);
  1055. X86IOMMUClass *dc_class = X86_IOMMU_CLASS(klass);
  1056. dc->reset = amdvi_reset;
  1057. dc->vmsd = &vmstate_amdvi;
  1058. dc->hotpluggable = false;
  1059. dc_class->realize = amdvi_realize;
  1060. /* Supported by the pc-q35-* machine types */
  1061. dc->user_creatable = true;
  1062. }
  1063. static const TypeInfo amdvi = {
  1064. .name = TYPE_AMD_IOMMU_DEVICE,
  1065. .parent = TYPE_X86_IOMMU_DEVICE,
  1066. .instance_size = sizeof(AMDVIState),
  1067. .instance_init = amdvi_instance_init,
  1068. .class_init = amdvi_class_init
  1069. };
  1070. static const TypeInfo amdviPCI = {
  1071. .name = "AMDVI-PCI",
  1072. .parent = TYPE_PCI_DEVICE,
  1073. .instance_size = sizeof(AMDVIPCIState),
  1074. .interfaces = (InterfaceInfo[]) {
  1075. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  1076. { },
  1077. },
  1078. };
  1079. static void amdvi_iommu_memory_region_class_init(ObjectClass *klass, void *data)
  1080. {
  1081. IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
  1082. imrc->translate = amdvi_translate;
  1083. imrc->notify_flag_changed = amdvi_iommu_notify_flag_changed;
  1084. }
  1085. static const TypeInfo amdvi_iommu_memory_region_info = {
  1086. .parent = TYPE_IOMMU_MEMORY_REGION,
  1087. .name = TYPE_AMD_IOMMU_MEMORY_REGION,
  1088. .class_init = amdvi_iommu_memory_region_class_init,
  1089. };
  1090. static void amdviPCI_register_types(void)
  1091. {
  1092. type_register_static(&amdviPCI);
  1093. type_register_static(&amdvi);
  1094. type_register_static(&amdvi_iommu_memory_region_info);
  1095. }
  1096. type_init(amdviPCI_register_types);