xen_pt.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. /*
  2. * Copyright (c) 2007, Neocleus Corporation.
  3. * Copyright (c) 2007, Intel Corporation.
  4. *
  5. * This work is licensed under the terms of the GNU GPL, version 2. See
  6. * the COPYING file in the top-level directory.
  7. *
  8. * Alex Novik <alex@neocleus.com>
  9. * Allen Kay <allen.m.kay@intel.com>
  10. * Guy Zana <guy@neocleus.com>
  11. *
  12. * This file implements direct PCI assignment to a HVM guest
  13. */
  14. /*
  15. * Interrupt Disable policy:
  16. *
  17. * INTx interrupt:
  18. * Initialize(register_real_device)
  19. * Map INTx(xc_physdev_map_pirq):
  20. * <fail>
  21. * - Set real Interrupt Disable bit to '1'.
  22. * - Set machine_irq and assigned_device->machine_irq to '0'.
  23. * * Don't bind INTx.
  24. *
  25. * Bind INTx(xc_domain_bind_pt_pci_irq):
  26. * <fail>
  27. * - Set real Interrupt Disable bit to '1'.
  28. * - Unmap INTx.
  29. * - Decrement xen_pt_mapped_machine_irq[machine_irq]
  30. * - Set assigned_device->machine_irq to '0'.
  31. *
  32. * Write to Interrupt Disable bit by guest software(xen_pt_cmd_reg_write)
  33. * Write '0'
  34. * - Set real bit to '0' if assigned_device->machine_irq isn't '0'.
  35. *
  36. * Write '1'
  37. * - Set real bit to '1'.
  38. *
  39. * MSI interrupt:
  40. * Initialize MSI register(xen_pt_msi_setup, xen_pt_msi_update)
  41. * Bind MSI(xc_domain_update_msi_irq)
  42. * <fail>
  43. * - Unmap MSI.
  44. * - Set dev->msi->pirq to '-1'.
  45. *
  46. * MSI-X interrupt:
  47. * Initialize MSI-X register(xen_pt_msix_update_one)
  48. * Bind MSI-X(xc_domain_update_msi_irq)
  49. * <fail>
  50. * - Unmap MSI-X.
  51. * - Set entry->pirq to '-1'.
  52. */
  53. #include "qemu/osdep.h"
  54. #include "qapi/error.h"
  55. #include <sys/ioctl.h>
  56. #include "hw/pci/pci.h"
  57. #include "hw/qdev-properties.h"
  58. #include "hw/xen/xen.h"
  59. #include "hw/i386/pc.h"
  60. #include "hw/xen/xen-legacy-backend.h"
  61. #include "xen_pt.h"
  62. #include "qemu/range.h"
  63. #include "exec/address-spaces.h"
  64. #define XEN_PT_NR_IRQS (256)
  65. static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0};
  66. void xen_pt_log(const PCIDevice *d, const char *f, ...)
  67. {
  68. va_list ap;
  69. va_start(ap, f);
  70. if (d) {
  71. fprintf(stderr, "[%02x:%02x.%d] ", pci_dev_bus_num(d),
  72. PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
  73. }
  74. vfprintf(stderr, f, ap);
  75. va_end(ap);
  76. }
  77. /* Config Space */
  78. static int xen_pt_pci_config_access_check(PCIDevice *d, uint32_t addr, int len)
  79. {
  80. /* check offset range */
  81. if (addr > 0xFF) {
  82. XEN_PT_ERR(d, "Failed to access register with offset exceeding 0xFF. "
  83. "(addr: 0x%02x, len: %d)\n", addr, len);
  84. return -1;
  85. }
  86. /* check read size */
  87. if ((len != 1) && (len != 2) && (len != 4)) {
  88. XEN_PT_ERR(d, "Failed to access register with invalid access length. "
  89. "(addr: 0x%02x, len: %d)\n", addr, len);
  90. return -1;
  91. }
  92. /* check offset alignment */
  93. if (addr & (len - 1)) {
  94. XEN_PT_ERR(d, "Failed to access register with invalid access size "
  95. "alignment. (addr: 0x%02x, len: %d)\n", addr, len);
  96. return -1;
  97. }
  98. return 0;
  99. }
  100. int xen_pt_bar_offset_to_index(uint32_t offset)
  101. {
  102. int index = 0;
  103. /* check Exp ROM BAR */
  104. if (offset == PCI_ROM_ADDRESS) {
  105. return PCI_ROM_SLOT;
  106. }
  107. /* calculate BAR index */
  108. index = (offset - PCI_BASE_ADDRESS_0) >> 2;
  109. if (index >= PCI_NUM_REGIONS) {
  110. return -1;
  111. }
  112. return index;
  113. }
  114. static uint32_t xen_pt_pci_read_config(PCIDevice *d, uint32_t addr, int len)
  115. {
  116. XenPCIPassthroughState *s = XEN_PT_DEVICE(d);
  117. uint32_t val = 0;
  118. XenPTRegGroup *reg_grp_entry = NULL;
  119. XenPTReg *reg_entry = NULL;
  120. int rc = 0;
  121. int emul_len = 0;
  122. uint32_t find_addr = addr;
  123. if (xen_pt_pci_config_access_check(d, addr, len)) {
  124. goto exit;
  125. }
  126. /* find register group entry */
  127. reg_grp_entry = xen_pt_find_reg_grp(s, addr);
  128. if (reg_grp_entry) {
  129. /* check 0-Hardwired register group */
  130. if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
  131. /* no need to emulate, just return 0 */
  132. val = 0;
  133. goto exit;
  134. }
  135. }
  136. /* read I/O device register value */
  137. rc = xen_host_pci_get_block(&s->real_device, addr, (uint8_t *)&val, len);
  138. if (rc < 0) {
  139. XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
  140. memset(&val, 0xff, len);
  141. }
  142. /* just return the I/O device register value for
  143. * passthrough type register group */
  144. if (reg_grp_entry == NULL) {
  145. goto exit;
  146. }
  147. /* adjust the read value to appropriate CFC-CFF window */
  148. val <<= (addr & 3) << 3;
  149. emul_len = len;
  150. /* loop around the guest requested size */
  151. while (emul_len > 0) {
  152. /* find register entry to be emulated */
  153. reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
  154. if (reg_entry) {
  155. XenPTRegInfo *reg = reg_entry->reg;
  156. uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
  157. uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
  158. uint8_t *ptr_val = NULL;
  159. valid_mask <<= (find_addr - real_offset) << 3;
  160. ptr_val = (uint8_t *)&val + (real_offset & 3);
  161. /* do emulation based on register size */
  162. switch (reg->size) {
  163. case 1:
  164. if (reg->u.b.read) {
  165. rc = reg->u.b.read(s, reg_entry, ptr_val, valid_mask);
  166. }
  167. break;
  168. case 2:
  169. if (reg->u.w.read) {
  170. rc = reg->u.w.read(s, reg_entry,
  171. (uint16_t *)ptr_val, valid_mask);
  172. }
  173. break;
  174. case 4:
  175. if (reg->u.dw.read) {
  176. rc = reg->u.dw.read(s, reg_entry,
  177. (uint32_t *)ptr_val, valid_mask);
  178. }
  179. break;
  180. }
  181. if (rc < 0) {
  182. xen_shutdown_fatal_error("Internal error: Invalid read "
  183. "emulation. (%s, rc: %d)\n",
  184. __func__, rc);
  185. return 0;
  186. }
  187. /* calculate next address to find */
  188. emul_len -= reg->size;
  189. if (emul_len > 0) {
  190. find_addr = real_offset + reg->size;
  191. }
  192. } else {
  193. /* nothing to do with passthrough type register,
  194. * continue to find next byte */
  195. emul_len--;
  196. find_addr++;
  197. }
  198. }
  199. /* need to shift back before returning them to pci bus emulator */
  200. val >>= ((addr & 3) << 3);
  201. exit:
  202. XEN_PT_LOG_CONFIG(d, addr, val, len);
  203. return val;
  204. }
  205. static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
  206. uint32_t val, int len)
  207. {
  208. XenPCIPassthroughState *s = XEN_PT_DEVICE(d);
  209. int index = 0;
  210. XenPTRegGroup *reg_grp_entry = NULL;
  211. int rc = 0;
  212. uint32_t read_val = 0, wb_mask;
  213. int emul_len = 0;
  214. XenPTReg *reg_entry = NULL;
  215. uint32_t find_addr = addr;
  216. XenPTRegInfo *reg = NULL;
  217. bool wp_flag = false;
  218. if (xen_pt_pci_config_access_check(d, addr, len)) {
  219. return;
  220. }
  221. XEN_PT_LOG_CONFIG(d, addr, val, len);
  222. /* check unused BAR register */
  223. index = xen_pt_bar_offset_to_index(addr);
  224. if ((index >= 0) && (val != 0)) {
  225. uint32_t chk = val;
  226. if (index == PCI_ROM_SLOT)
  227. chk |= (uint32_t)~PCI_ROM_ADDRESS_MASK;
  228. if ((chk != XEN_PT_BAR_ALLF) &&
  229. (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) {
  230. XEN_PT_WARN(d, "Guest attempt to set address to unused "
  231. "Base Address Register. (addr: 0x%02x, len: %d)\n",
  232. addr, len);
  233. }
  234. }
  235. /* find register group entry */
  236. reg_grp_entry = xen_pt_find_reg_grp(s, addr);
  237. if (reg_grp_entry) {
  238. /* check 0-Hardwired register group */
  239. if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) {
  240. /* ignore silently */
  241. XEN_PT_WARN(d, "Access to 0-Hardwired register. "
  242. "(addr: 0x%02x, len: %d)\n", addr, len);
  243. return;
  244. }
  245. }
  246. rc = xen_host_pci_get_block(&s->real_device, addr,
  247. (uint8_t *)&read_val, len);
  248. if (rc < 0) {
  249. XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
  250. memset(&read_val, 0xff, len);
  251. wb_mask = 0;
  252. } else {
  253. wb_mask = 0xFFFFFFFF >> ((4 - len) << 3);
  254. }
  255. /* pass directly to the real device for passthrough type register group */
  256. if (reg_grp_entry == NULL) {
  257. if (!s->permissive) {
  258. wb_mask = 0;
  259. wp_flag = true;
  260. }
  261. goto out;
  262. }
  263. memory_region_transaction_begin();
  264. pci_default_write_config(d, addr, val, len);
  265. /* adjust the read and write value to appropriate CFC-CFF window */
  266. read_val <<= (addr & 3) << 3;
  267. val <<= (addr & 3) << 3;
  268. emul_len = len;
  269. /* loop around the guest requested size */
  270. while (emul_len > 0) {
  271. /* find register entry to be emulated */
  272. reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr);
  273. if (reg_entry) {
  274. reg = reg_entry->reg;
  275. uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
  276. uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
  277. uint8_t *ptr_val = NULL;
  278. uint32_t wp_mask = reg->emu_mask | reg->ro_mask;
  279. valid_mask <<= (find_addr - real_offset) << 3;
  280. ptr_val = (uint8_t *)&val + (real_offset & 3);
  281. if (!s->permissive) {
  282. wp_mask |= reg->res_mask;
  283. }
  284. if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) {
  285. wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3))
  286. << ((len - emul_len) << 3));
  287. }
  288. /* do emulation based on register size */
  289. switch (reg->size) {
  290. case 1:
  291. if (reg->u.b.write) {
  292. rc = reg->u.b.write(s, reg_entry, ptr_val,
  293. read_val >> ((real_offset & 3) << 3),
  294. valid_mask);
  295. }
  296. break;
  297. case 2:
  298. if (reg->u.w.write) {
  299. rc = reg->u.w.write(s, reg_entry, (uint16_t *)ptr_val,
  300. (read_val >> ((real_offset & 3) << 3)),
  301. valid_mask);
  302. }
  303. break;
  304. case 4:
  305. if (reg->u.dw.write) {
  306. rc = reg->u.dw.write(s, reg_entry, (uint32_t *)ptr_val,
  307. (read_val >> ((real_offset & 3) << 3)),
  308. valid_mask);
  309. }
  310. break;
  311. }
  312. if (rc < 0) {
  313. xen_shutdown_fatal_error("Internal error: Invalid write"
  314. " emulation. (%s, rc: %d)\n",
  315. __func__, rc);
  316. return;
  317. }
  318. /* calculate next address to find */
  319. emul_len -= reg->size;
  320. if (emul_len > 0) {
  321. find_addr = real_offset + reg->size;
  322. }
  323. } else {
  324. /* nothing to do with passthrough type register,
  325. * continue to find next byte */
  326. if (!s->permissive) {
  327. wb_mask &= ~(0xff << ((len - emul_len) << 3));
  328. /* Unused BARs will make it here, but we don't want to issue
  329. * warnings for writes to them (bogus writes get dealt with
  330. * above).
  331. */
  332. if (index < 0) {
  333. wp_flag = true;
  334. }
  335. }
  336. emul_len--;
  337. find_addr++;
  338. }
  339. }
  340. /* need to shift back before passing them to xen_host_pci_set_block. */
  341. val >>= (addr & 3) << 3;
  342. memory_region_transaction_commit();
  343. out:
  344. if (wp_flag && !s->permissive_warned) {
  345. s->permissive_warned = true;
  346. xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n",
  347. addr, len * 2, wb_mask);
  348. xen_pt_log(d, "If the device doesn't work, try enabling permissive mode\n");
  349. xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n");
  350. }
  351. for (index = 0; wb_mask; index += len) {
  352. /* unknown regs are passed through */
  353. while (!(wb_mask & 0xff)) {
  354. index++;
  355. wb_mask >>= 8;
  356. }
  357. len = 0;
  358. do {
  359. len++;
  360. wb_mask >>= 8;
  361. } while (wb_mask & 0xff);
  362. rc = xen_host_pci_set_block(&s->real_device, addr + index,
  363. (uint8_t *)&val + index, len);
  364. if (rc < 0) {
  365. XEN_PT_ERR(d, "xen_host_pci_set_block failed. return value: %d.\n", rc);
  366. }
  367. }
  368. }
  369. /* register regions */
  370. static uint64_t xen_pt_bar_read(void *o, hwaddr addr,
  371. unsigned size)
  372. {
  373. PCIDevice *d = o;
  374. /* if this function is called, that probably means that there is a
  375. * misconfiguration of the IOMMU. */
  376. XEN_PT_ERR(d, "Should not read BAR through QEMU. @0x"TARGET_FMT_plx"\n",
  377. addr);
  378. return 0;
  379. }
  380. static void xen_pt_bar_write(void *o, hwaddr addr, uint64_t val,
  381. unsigned size)
  382. {
  383. PCIDevice *d = o;
  384. /* Same comment as xen_pt_bar_read function */
  385. XEN_PT_ERR(d, "Should not write BAR through QEMU. @0x"TARGET_FMT_plx"\n",
  386. addr);
  387. }
  388. static const MemoryRegionOps ops = {
  389. .endianness = DEVICE_NATIVE_ENDIAN,
  390. .read = xen_pt_bar_read,
  391. .write = xen_pt_bar_write,
  392. };
  393. static int xen_pt_register_regions(XenPCIPassthroughState *s, uint16_t *cmd)
  394. {
  395. int i = 0;
  396. XenHostPCIDevice *d = &s->real_device;
  397. /* Register PIO/MMIO BARs */
  398. for (i = 0; i < PCI_ROM_SLOT; i++) {
  399. XenHostPCIIORegion *r = &d->io_regions[i];
  400. uint8_t type;
  401. if (r->base_addr == 0 || r->size == 0) {
  402. continue;
  403. }
  404. s->bases[i].access.u = r->base_addr;
  405. if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) {
  406. type = PCI_BASE_ADDRESS_SPACE_IO;
  407. *cmd |= PCI_COMMAND_IO;
  408. } else {
  409. type = PCI_BASE_ADDRESS_SPACE_MEMORY;
  410. if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) {
  411. type |= PCI_BASE_ADDRESS_MEM_PREFETCH;
  412. }
  413. if (r->type & XEN_HOST_PCI_REGION_TYPE_MEM_64) {
  414. type |= PCI_BASE_ADDRESS_MEM_TYPE_64;
  415. }
  416. *cmd |= PCI_COMMAND_MEMORY;
  417. }
  418. memory_region_init_io(&s->bar[i], OBJECT(s), &ops, &s->dev,
  419. "xen-pci-pt-bar", r->size);
  420. pci_register_bar(&s->dev, i, type, &s->bar[i]);
  421. XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%08"PRIx64
  422. " base_addr=0x%08"PRIx64" type: %#x)\n",
  423. i, r->size, r->base_addr, type);
  424. }
  425. /* Register expansion ROM address */
  426. if (d->rom.base_addr && d->rom.size) {
  427. uint32_t bar_data = 0;
  428. /* Re-set BAR reported by OS, otherwise ROM can't be read. */
  429. if (xen_host_pci_get_long(d, PCI_ROM_ADDRESS, &bar_data)) {
  430. return 0;
  431. }
  432. if ((bar_data & PCI_ROM_ADDRESS_MASK) == 0) {
  433. bar_data |= d->rom.base_addr & PCI_ROM_ADDRESS_MASK;
  434. xen_host_pci_set_long(d, PCI_ROM_ADDRESS, bar_data);
  435. }
  436. s->bases[PCI_ROM_SLOT].access.maddr = d->rom.base_addr;
  437. memory_region_init_io(&s->rom, OBJECT(s), &ops, &s->dev,
  438. "xen-pci-pt-rom", d->rom.size);
  439. pci_register_bar(&s->dev, PCI_ROM_SLOT, PCI_BASE_ADDRESS_MEM_PREFETCH,
  440. &s->rom);
  441. XEN_PT_LOG(&s->dev, "Expansion ROM registered (size=0x%08"PRIx64
  442. " base_addr=0x%08"PRIx64")\n",
  443. d->rom.size, d->rom.base_addr);
  444. }
  445. xen_pt_register_vga_regions(d);
  446. return 0;
  447. }
  448. /* region mapping */
  449. static int xen_pt_bar_from_region(XenPCIPassthroughState *s, MemoryRegion *mr)
  450. {
  451. int i = 0;
  452. for (i = 0; i < PCI_NUM_REGIONS - 1; i++) {
  453. if (mr == &s->bar[i]) {
  454. return i;
  455. }
  456. }
  457. if (mr == &s->rom) {
  458. return PCI_ROM_SLOT;
  459. }
  460. return -1;
  461. }
  462. /*
  463. * This function checks if an io_region overlaps an io_region from another
  464. * device. The io_region to check is provided with (addr, size and type)
  465. * A callback can be provided and will be called for every region that is
  466. * overlapped.
  467. * The return value indicates if the region is overlappsed */
  468. struct CheckBarArgs {
  469. XenPCIPassthroughState *s;
  470. pcibus_t addr;
  471. pcibus_t size;
  472. uint8_t type;
  473. bool rc;
  474. };
  475. static void xen_pt_check_bar_overlap(PCIBus *bus, PCIDevice *d, void *opaque)
  476. {
  477. struct CheckBarArgs *arg = opaque;
  478. XenPCIPassthroughState *s = arg->s;
  479. uint8_t type = arg->type;
  480. int i;
  481. if (d->devfn == s->dev.devfn) {
  482. return;
  483. }
  484. /* xxx: This ignores bridges. */
  485. for (i = 0; i < PCI_NUM_REGIONS; i++) {
  486. const PCIIORegion *r = &d->io_regions[i];
  487. if (!r->size) {
  488. continue;
  489. }
  490. if ((type & PCI_BASE_ADDRESS_SPACE_IO)
  491. != (r->type & PCI_BASE_ADDRESS_SPACE_IO)) {
  492. continue;
  493. }
  494. if (ranges_overlap(arg->addr, arg->size, r->addr, r->size)) {
  495. XEN_PT_WARN(&s->dev,
  496. "Overlapped to device [%02x:%02x.%d] Region: %i"
  497. " (addr: %#"FMT_PCIBUS", len: %#"FMT_PCIBUS")\n",
  498. pci_bus_num(bus), PCI_SLOT(d->devfn),
  499. PCI_FUNC(d->devfn), i, r->addr, r->size);
  500. arg->rc = true;
  501. }
  502. }
  503. }
  504. static void xen_pt_region_update(XenPCIPassthroughState *s,
  505. MemoryRegionSection *sec, bool adding)
  506. {
  507. PCIDevice *d = &s->dev;
  508. MemoryRegion *mr = sec->mr;
  509. int bar = -1;
  510. int rc;
  511. int op = adding ? DPCI_ADD_MAPPING : DPCI_REMOVE_MAPPING;
  512. struct CheckBarArgs args = {
  513. .s = s,
  514. .addr = sec->offset_within_address_space,
  515. .size = int128_get64(sec->size),
  516. .rc = false,
  517. };
  518. bar = xen_pt_bar_from_region(s, mr);
  519. if (bar == -1 && (!s->msix || &s->msix->mmio != mr)) {
  520. return;
  521. }
  522. if (s->msix && &s->msix->mmio == mr) {
  523. if (adding) {
  524. s->msix->mmio_base_addr = sec->offset_within_address_space;
  525. rc = xen_pt_msix_update_remap(s, s->msix->bar_index);
  526. }
  527. return;
  528. }
  529. args.type = d->io_regions[bar].type;
  530. pci_for_each_device(pci_get_bus(d), pci_dev_bus_num(d),
  531. xen_pt_check_bar_overlap, &args);
  532. if (args.rc) {
  533. XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS
  534. ", len: %#"FMT_PCIBUS") is overlapped.\n",
  535. bar, sec->offset_within_address_space,
  536. int128_get64(sec->size));
  537. }
  538. if (d->io_regions[bar].type & PCI_BASE_ADDRESS_SPACE_IO) {
  539. uint32_t guest_port = sec->offset_within_address_space;
  540. uint32_t machine_port = s->bases[bar].access.pio_base;
  541. uint32_t size = int128_get64(sec->size);
  542. rc = xc_domain_ioport_mapping(xen_xc, xen_domid,
  543. guest_port, machine_port, size,
  544. op);
  545. if (rc) {
  546. XEN_PT_ERR(d, "%s ioport mapping failed! (err: %i)\n",
  547. adding ? "create new" : "remove old", errno);
  548. }
  549. } else {
  550. pcibus_t guest_addr = sec->offset_within_address_space;
  551. pcibus_t machine_addr = s->bases[bar].access.maddr
  552. + sec->offset_within_region;
  553. pcibus_t size = int128_get64(sec->size);
  554. rc = xc_domain_memory_mapping(xen_xc, xen_domid,
  555. XEN_PFN(guest_addr + XC_PAGE_SIZE - 1),
  556. XEN_PFN(machine_addr + XC_PAGE_SIZE - 1),
  557. XEN_PFN(size + XC_PAGE_SIZE - 1),
  558. op);
  559. if (rc) {
  560. XEN_PT_ERR(d, "%s mem mapping failed! (err: %i)\n",
  561. adding ? "create new" : "remove old", errno);
  562. }
  563. }
  564. }
  565. static void xen_pt_region_add(MemoryListener *l, MemoryRegionSection *sec)
  566. {
  567. XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
  568. memory_listener);
  569. memory_region_ref(sec->mr);
  570. xen_pt_region_update(s, sec, true);
  571. }
  572. static void xen_pt_region_del(MemoryListener *l, MemoryRegionSection *sec)
  573. {
  574. XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
  575. memory_listener);
  576. xen_pt_region_update(s, sec, false);
  577. memory_region_unref(sec->mr);
  578. }
  579. static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec)
  580. {
  581. XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
  582. io_listener);
  583. memory_region_ref(sec->mr);
  584. xen_pt_region_update(s, sec, true);
  585. }
  586. static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec)
  587. {
  588. XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
  589. io_listener);
  590. xen_pt_region_update(s, sec, false);
  591. memory_region_unref(sec->mr);
  592. }
  593. static const MemoryListener xen_pt_memory_listener = {
  594. .region_add = xen_pt_region_add,
  595. .region_del = xen_pt_region_del,
  596. .priority = 10,
  597. };
  598. static const MemoryListener xen_pt_io_listener = {
  599. .region_add = xen_pt_io_region_add,
  600. .region_del = xen_pt_io_region_del,
  601. .priority = 10,
  602. };
  603. static void
  604. xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,
  605. XenHostPCIDevice *dev)
  606. {
  607. uint16_t gpu_dev_id;
  608. PCIDevice *d = &s->dev;
  609. gpu_dev_id = dev->device_id;
  610. igd_passthrough_isa_bridge_create(pci_get_bus(d), gpu_dev_id);
  611. }
  612. /* destroy. */
  613. static void xen_pt_destroy(PCIDevice *d) {
  614. XenPCIPassthroughState *s = XEN_PT_DEVICE(d);
  615. XenHostPCIDevice *host_dev = &s->real_device;
  616. uint8_t machine_irq = s->machine_irq;
  617. uint8_t intx;
  618. int rc;
  619. if (machine_irq && !xen_host_pci_device_closed(&s->real_device)) {
  620. intx = xen_pt_pci_intx(s);
  621. rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq,
  622. PT_IRQ_TYPE_PCI,
  623. pci_dev_bus_num(d),
  624. PCI_SLOT(s->dev.devfn),
  625. intx,
  626. 0 /* isa_irq */);
  627. if (rc < 0) {
  628. XEN_PT_ERR(d, "unbinding of interrupt INT%c failed."
  629. " (machine irq: %i, err: %d)"
  630. " But bravely continuing on..\n",
  631. 'a' + intx, machine_irq, errno);
  632. }
  633. }
  634. /* N.B. xen_pt_config_delete takes care of freeing them. */
  635. if (s->msi) {
  636. xen_pt_msi_disable(s);
  637. }
  638. if (s->msix) {
  639. xen_pt_msix_disable(s);
  640. }
  641. if (machine_irq) {
  642. xen_pt_mapped_machine_irq[machine_irq]--;
  643. if (xen_pt_mapped_machine_irq[machine_irq] == 0) {
  644. rc = xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq);
  645. if (rc < 0) {
  646. XEN_PT_ERR(d, "unmapping of interrupt %i failed. (err: %d)"
  647. " But bravely continuing on..\n",
  648. machine_irq, errno);
  649. }
  650. }
  651. s->machine_irq = 0;
  652. }
  653. /* delete all emulated config registers */
  654. xen_pt_config_delete(s);
  655. xen_pt_unregister_vga_regions(host_dev);
  656. if (s->listener_set) {
  657. memory_listener_unregister(&s->memory_listener);
  658. memory_listener_unregister(&s->io_listener);
  659. s->listener_set = false;
  660. }
  661. if (!xen_host_pci_device_closed(&s->real_device)) {
  662. xen_host_pci_device_put(&s->real_device);
  663. }
  664. }
  665. /* init */
  666. static void xen_pt_realize(PCIDevice *d, Error **errp)
  667. {
  668. XenPCIPassthroughState *s = XEN_PT_DEVICE(d);
  669. int i, rc = 0;
  670. uint8_t machine_irq = 0, scratch;
  671. uint16_t cmd = 0;
  672. int pirq = XEN_PT_UNASSIGNED_PIRQ;
  673. Error *err = NULL;
  674. /* register real device */
  675. XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d"
  676. " to devfn %#x\n",
  677. s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function,
  678. s->dev.devfn);
  679. xen_host_pci_device_get(&s->real_device,
  680. s->hostaddr.domain, s->hostaddr.bus,
  681. s->hostaddr.slot, s->hostaddr.function,
  682. &err);
  683. if (err) {
  684. error_append_hint(&err, "Failed to \"open\" the real pci device");
  685. error_propagate(errp, err);
  686. return;
  687. }
  688. s->is_virtfn = s->real_device.is_virtfn;
  689. if (s->is_virtfn) {
  690. XEN_PT_LOG(d, "%04x:%02x:%02x.%d is a SR-IOV Virtual Function\n",
  691. s->real_device.domain, s->real_device.bus,
  692. s->real_device.dev, s->real_device.func);
  693. }
  694. /* Initialize virtualized PCI configuration (Extended 256 Bytes) */
  695. memset(d->config, 0, PCI_CONFIG_SPACE_SIZE);
  696. s->memory_listener = xen_pt_memory_listener;
  697. s->io_listener = xen_pt_io_listener;
  698. /* Setup VGA bios for passthrough GFX */
  699. if ((s->real_device.domain == 0) && (s->real_device.bus == 0) &&
  700. (s->real_device.dev == 2) && (s->real_device.func == 0)) {
  701. if (!is_igd_vga_passthrough(&s->real_device)) {
  702. error_setg(errp, "Need to enable igd-passthru if you're trying"
  703. " to passthrough IGD GFX");
  704. xen_host_pci_device_put(&s->real_device);
  705. return;
  706. }
  707. xen_pt_setup_vga(s, &s->real_device, &err);
  708. if (err) {
  709. error_append_hint(&err, "Setup VGA BIOS of passthrough"
  710. " GFX failed");
  711. error_propagate(errp, err);
  712. xen_host_pci_device_put(&s->real_device);
  713. return;
  714. }
  715. /* Register ISA bridge for passthrough GFX. */
  716. xen_igd_passthrough_isa_bridge_create(s, &s->real_device);
  717. }
  718. /* Handle real device's MMIO/PIO BARs */
  719. xen_pt_register_regions(s, &cmd);
  720. /* reinitialize each config register to be emulated */
  721. xen_pt_config_init(s, &err);
  722. if (err) {
  723. error_append_hint(&err, "PCI Config space initialisation failed");
  724. error_propagate(errp, err);
  725. rc = -1;
  726. goto err_out;
  727. }
  728. /* Bind interrupt */
  729. rc = xen_host_pci_get_byte(&s->real_device, PCI_INTERRUPT_PIN, &scratch);
  730. if (rc) {
  731. error_setg_errno(errp, errno, "Failed to read PCI_INTERRUPT_PIN");
  732. goto err_out;
  733. }
  734. if (!scratch) {
  735. XEN_PT_LOG(d, "no pin interrupt\n");
  736. goto out;
  737. }
  738. machine_irq = s->real_device.irq;
  739. if (machine_irq == 0) {
  740. XEN_PT_LOG(d, "machine irq is 0\n");
  741. cmd |= PCI_COMMAND_INTX_DISABLE;
  742. goto out;
  743. }
  744. rc = xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq);
  745. if (rc < 0) {
  746. error_setg_errno(errp, errno, "Mapping machine irq %u to"
  747. " pirq %i failed", machine_irq, pirq);
  748. /* Disable PCI intx assertion (turn on bit10 of devctl) */
  749. cmd |= PCI_COMMAND_INTX_DISABLE;
  750. machine_irq = 0;
  751. s->machine_irq = 0;
  752. } else {
  753. machine_irq = pirq;
  754. s->machine_irq = pirq;
  755. xen_pt_mapped_machine_irq[machine_irq]++;
  756. }
  757. /* bind machine_irq to device */
  758. if (machine_irq != 0) {
  759. uint8_t e_intx = xen_pt_pci_intx(s);
  760. rc = xc_domain_bind_pt_pci_irq(xen_xc, xen_domid, machine_irq,
  761. pci_dev_bus_num(d),
  762. PCI_SLOT(d->devfn),
  763. e_intx);
  764. if (rc < 0) {
  765. error_setg_errno(errp, errno, "Binding of interrupt %u failed",
  766. e_intx);
  767. /* Disable PCI intx assertion (turn on bit10 of devctl) */
  768. cmd |= PCI_COMMAND_INTX_DISABLE;
  769. xen_pt_mapped_machine_irq[machine_irq]--;
  770. if (xen_pt_mapped_machine_irq[machine_irq] == 0) {
  771. if (xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq)) {
  772. error_setg_errno(errp, errno, "Unmapping of machine"
  773. " interrupt %u failed", machine_irq);
  774. }
  775. }
  776. s->machine_irq = 0;
  777. }
  778. }
  779. out:
  780. if (cmd) {
  781. uint16_t val;
  782. rc = xen_host_pci_get_word(&s->real_device, PCI_COMMAND, &val);
  783. if (rc) {
  784. error_setg_errno(errp, errno, "Failed to read PCI_COMMAND");
  785. goto err_out;
  786. } else {
  787. val |= cmd;
  788. rc = xen_host_pci_set_word(&s->real_device, PCI_COMMAND, val);
  789. if (rc) {
  790. error_setg_errno(errp, errno, "Failed to write PCI_COMMAND"
  791. " val = 0x%x", val);
  792. goto err_out;
  793. }
  794. }
  795. }
  796. memory_listener_register(&s->memory_listener, &address_space_memory);
  797. memory_listener_register(&s->io_listener, &address_space_io);
  798. s->listener_set = true;
  799. XEN_PT_LOG(d,
  800. "Real physical device %02x:%02x.%d registered successfully\n",
  801. s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function);
  802. return;
  803. err_out:
  804. for (i = 0; i < PCI_ROM_SLOT; i++) {
  805. object_unparent(OBJECT(&s->bar[i]));
  806. }
  807. object_unparent(OBJECT(&s->rom));
  808. xen_pt_destroy(d);
  809. assert(rc);
  810. }
  811. static void xen_pt_unregister_device(PCIDevice *d)
  812. {
  813. xen_pt_destroy(d);
  814. }
  815. static Property xen_pci_passthrough_properties[] = {
  816. DEFINE_PROP_PCI_HOST_DEVADDR("hostaddr", XenPCIPassthroughState, hostaddr),
  817. DEFINE_PROP_BOOL("permissive", XenPCIPassthroughState, permissive, false),
  818. DEFINE_PROP_END_OF_LIST(),
  819. };
  820. static void xen_pci_passthrough_instance_init(Object *obj)
  821. {
  822. /* QEMU_PCI_CAP_EXPRESS initialization does not depend on QEMU command
  823. * line, therefore, no need to wait to realize like other devices */
  824. PCI_DEVICE(obj)->cap_present |= QEMU_PCI_CAP_EXPRESS;
  825. }
  826. static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data)
  827. {
  828. DeviceClass *dc = DEVICE_CLASS(klass);
  829. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  830. k->realize = xen_pt_realize;
  831. k->exit = xen_pt_unregister_device;
  832. k->config_read = xen_pt_pci_read_config;
  833. k->config_write = xen_pt_pci_write_config;
  834. set_bit(DEVICE_CATEGORY_MISC, dc->categories);
  835. dc->desc = "Assign an host PCI device with Xen";
  836. dc->props = xen_pci_passthrough_properties;
  837. };
  838. static void xen_pci_passthrough_finalize(Object *obj)
  839. {
  840. XenPCIPassthroughState *s = XEN_PT_DEVICE(obj);
  841. xen_pt_msix_delete(s);
  842. }
  843. static const TypeInfo xen_pci_passthrough_info = {
  844. .name = TYPE_XEN_PT_DEVICE,
  845. .parent = TYPE_PCI_DEVICE,
  846. .instance_size = sizeof(XenPCIPassthroughState),
  847. .instance_finalize = xen_pci_passthrough_finalize,
  848. .class_init = xen_pci_passthrough_class_init,
  849. .instance_init = xen_pci_passthrough_instance_init,
  850. .interfaces = (InterfaceInfo[]) {
  851. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  852. { INTERFACE_PCIE_DEVICE },
  853. { },
  854. },
  855. };
  856. static void xen_pci_passthrough_register_types(void)
  857. {
  858. type_register_static(&xen_pci_passthrough_info);
  859. }
  860. type_init(xen_pci_passthrough_register_types)