Revision 96adc5c7
b/hw/vfio_pci.c | ||
---|---|---|
1506 | 1506 |
return next - pos; |
1507 | 1507 |
} |
1508 | 1508 |
|
1509 |
static void vfio_set_word_bits(uint8_t *buf, uint16_t val, uint16_t mask) |
|
1510 |
{ |
|
1511 |
pci_set_word(buf, (pci_get_word(buf) & ~mask) | val); |
|
1512 |
} |
|
1513 |
|
|
1514 |
static void vfio_add_emulated_word(VFIODevice *vdev, int pos, |
|
1515 |
uint16_t val, uint16_t mask) |
|
1516 |
{ |
|
1517 |
vfio_set_word_bits(vdev->pdev.config + pos, val, mask); |
|
1518 |
vfio_set_word_bits(vdev->pdev.wmask + pos, ~mask, mask); |
|
1519 |
vfio_set_word_bits(vdev->emulated_config_bits + pos, mask, mask); |
|
1520 |
} |
|
1521 |
|
|
1522 |
static void vfio_set_long_bits(uint8_t *buf, uint32_t val, uint32_t mask) |
|
1523 |
{ |
|
1524 |
pci_set_long(buf, (pci_get_long(buf) & ~mask) | val); |
|
1525 |
} |
|
1526 |
|
|
1527 |
static void vfio_add_emulated_long(VFIODevice *vdev, int pos, |
|
1528 |
uint32_t val, uint32_t mask) |
|
1529 |
{ |
|
1530 |
vfio_set_long_bits(vdev->pdev.config + pos, val, mask); |
|
1531 |
vfio_set_long_bits(vdev->pdev.wmask + pos, ~mask, mask); |
|
1532 |
vfio_set_long_bits(vdev->emulated_config_bits + pos, mask, mask); |
|
1533 |
} |
|
1534 |
|
|
1535 |
static int vfio_setup_pcie_cap(VFIODevice *vdev, int pos, uint8_t size) |
|
1536 |
{ |
|
1537 |
uint16_t flags; |
|
1538 |
uint8_t type; |
|
1539 |
|
|
1540 |
flags = pci_get_word(vdev->pdev.config + pos + PCI_CAP_FLAGS); |
|
1541 |
type = (flags & PCI_EXP_FLAGS_TYPE) >> 4; |
|
1542 |
|
|
1543 |
if (type != PCI_EXP_TYPE_ENDPOINT && |
|
1544 |
type != PCI_EXP_TYPE_LEG_END && |
|
1545 |
type != PCI_EXP_TYPE_RC_END) { |
|
1546 |
|
|
1547 |
error_report("vfio: Assignment of PCIe type 0x%x " |
|
1548 |
"devices is not currently supported", type); |
|
1549 |
return -EINVAL; |
|
1550 |
} |
|
1551 |
|
|
1552 |
if (!pci_bus_is_express(vdev->pdev.bus)) { |
|
1553 |
/* |
|
1554 |
* Use express capability as-is on PCI bus. It doesn't make much |
|
1555 |
* sense to even expose, but some drivers (ex. tg3) depend on it |
|
1556 |
* and guests don't seem to be particular about it. We'll need |
|
1557 |
* to revist this or force express devices to express buses if we |
|
1558 |
* ever expose an IOMMU to the guest. |
|
1559 |
*/ |
|
1560 |
} else if (pci_bus_is_root(vdev->pdev.bus)) { |
|
1561 |
/* |
|
1562 |
* On a Root Complex bus Endpoints become Root Complex Integrated |
|
1563 |
* Endpoints, which changes the type and clears the LNK & LNK2 fields. |
|
1564 |
*/ |
|
1565 |
if (type == PCI_EXP_TYPE_ENDPOINT) { |
|
1566 |
vfio_add_emulated_word(vdev, pos + PCI_CAP_FLAGS, |
|
1567 |
PCI_EXP_TYPE_RC_END << 4, |
|
1568 |
PCI_EXP_FLAGS_TYPE); |
|
1569 |
|
|
1570 |
/* Link Capabilities, Status, and Control goes away */ |
|
1571 |
if (size > PCI_EXP_LNKCTL) { |
|
1572 |
vfio_add_emulated_long(vdev, pos + PCI_EXP_LNKCAP, 0, ~0); |
|
1573 |
vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL, 0, ~0); |
|
1574 |
vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKSTA, 0, ~0); |
|
1575 |
|
|
1576 |
#ifndef PCI_EXP_LNKCAP2 |
|
1577 |
#define PCI_EXP_LNKCAP2 44 |
|
1578 |
#endif |
|
1579 |
#ifndef PCI_EXP_LNKSTA2 |
|
1580 |
#define PCI_EXP_LNKSTA2 50 |
|
1581 |
#endif |
|
1582 |
/* Link 2 Capabilities, Status, and Control goes away */ |
|
1583 |
if (size > PCI_EXP_LNKCAP2) { |
|
1584 |
vfio_add_emulated_long(vdev, pos + PCI_EXP_LNKCAP2, 0, ~0); |
|
1585 |
vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL2, 0, ~0); |
|
1586 |
vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKSTA2, 0, ~0); |
|
1587 |
} |
|
1588 |
} |
|
1589 |
|
|
1590 |
} else if (type == PCI_EXP_TYPE_LEG_END) { |
|
1591 |
/* |
|
1592 |
* Legacy endpoints don't belong on the root complex. Windows |
|
1593 |
* seems to be happier with devices if we skip the capability. |
|
1594 |
*/ |
|
1595 |
return 0; |
|
1596 |
} |
|
1597 |
|
|
1598 |
} else { |
|
1599 |
/* |
|
1600 |
* Convert Root Complex Integrated Endpoints to regular endpoints. |
|
1601 |
* These devices don't support LNK/LNK2 capabilities, so make them up. |
|
1602 |
*/ |
|
1603 |
if (type == PCI_EXP_TYPE_RC_END) { |
|
1604 |
vfio_add_emulated_word(vdev, pos + PCI_CAP_FLAGS, |
|
1605 |
PCI_EXP_TYPE_ENDPOINT << 4, |
|
1606 |
PCI_EXP_FLAGS_TYPE); |
|
1607 |
vfio_add_emulated_long(vdev, pos + PCI_EXP_LNKCAP, |
|
1608 |
PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25, ~0); |
|
1609 |
vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL, 0, ~0); |
|
1610 |
} |
|
1611 |
|
|
1612 |
/* Mark the Link Status bits as emulated to allow virtual negotiation */ |
|
1613 |
vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKSTA, |
|
1614 |
pci_get_word(vdev->pdev.config + pos + |
|
1615 |
PCI_EXP_LNKSTA), |
|
1616 |
PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); |
|
1617 |
} |
|
1618 |
|
|
1619 |
pos = pci_add_capability(&vdev->pdev, PCI_CAP_ID_EXP, pos, size); |
|
1620 |
if (pos >= 0) { |
|
1621 |
vdev->pdev.exp.exp_cap = pos; |
|
1622 |
} |
|
1623 |
|
|
1624 |
return pos; |
|
1625 |
} |
|
1626 |
|
|
1509 | 1627 |
static int vfio_add_std_cap(VFIODevice *vdev, uint8_t pos) |
1510 | 1628 |
{ |
1511 | 1629 |
PCIDevice *pdev = &vdev->pdev; |
... | ... | |
1536 | 1654 |
return ret; |
1537 | 1655 |
} |
1538 | 1656 |
} else { |
1539 |
pdev->config[PCI_CAPABILITY_LIST] = 0; /* Begin the rebuild */ |
|
1657 |
/* Begin the rebuild, use QEMU emulated list bits */ |
|
1658 |
pdev->config[PCI_CAPABILITY_LIST] = 0; |
|
1659 |
vdev->emulated_config_bits[PCI_CAPABILITY_LIST] = 0xff; |
|
1660 |
vdev->emulated_config_bits[PCI_STATUS] |= PCI_STATUS_CAP_LIST; |
|
1540 | 1661 |
} |
1541 | 1662 |
|
1663 |
/* Use emulated next pointer to allow dropping caps */ |
|
1664 |
pci_set_byte(vdev->emulated_config_bits + pos + 1, 0xff); |
|
1665 |
|
|
1542 | 1666 |
switch (cap_id) { |
1543 | 1667 |
case PCI_CAP_ID_MSI: |
1544 | 1668 |
ret = vfio_setup_msi(vdev, pos); |
1545 | 1669 |
break; |
1670 |
case PCI_CAP_ID_EXP: |
|
1671 |
ret = vfio_setup_pcie_cap(vdev, pos, size); |
|
1672 |
break; |
|
1546 | 1673 |
case PCI_CAP_ID_MSIX: |
1547 | 1674 |
ret = vfio_setup_msix(vdev, pos); |
1548 | 1675 |
break; |
Also available in: Unified diff