Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ config VIRTIO_IOMMU
config XEN_IOMMU
bool "Xen IOMMU driver"
depends on X86 && XEN
# Built-in, and asks pcifront for a device's machine BDF.
depends on XEN_PCIDEV_FRONTEND != m
select IOMMU_API
select IOMMU_IO_PGTABLE
help
Expand Down
4 changes: 3 additions & 1 deletion drivers/iommu/dma-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,9 @@ static int iova_reserve_iommu_regions(struct device *dev,
* are invented -- pcifront hands out iomem_resource itself, and a PVH
* guest with no host bridge _CRS gets Linux's catch-all default. There
* is nothing meaningful to reserve, and reserving it leaves no usable
* IOVA space whatsoever.
* IOVA space whatsoever. Dom0 sees the real host bridges and keeps the
* reservation: without it an IOVA can land on a sibling's BAR, and a
* fabric without ACS delivers the DMA there instead of to the IOMMU.
*/
if (dev_is_pci(dev) && !xen_iommu_manages_iova(dev)) {
ret = iova_reserve_pci_windows(to_pci_dev(dev), iovad);
Expand Down
10 changes: 9 additions & 1 deletion drivers/iommu/xen-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,17 @@ static struct iommu_ops xen_iommu_ops = {
},
};

/*
* True when the host-bridge windows @dev sees are not the machine's and
* dma-iommu must not reserve them: a guest's IOVA space belongs to the
* hypervisor, and the windows it sees are invented. Dom0 sees the real
* host bridges, whose windows route to real BARs, so there the reservation
* stands as on bare metal.
*/
bool xen_iommu_manages_iova(struct device *dev)
{
return dev->iommu && dev_iommu_ops(dev) == &xen_iommu_ops;
return !xen_initial_domain() && dev->iommu &&
dev_iommu_ops(dev) == &xen_iommu_ops;
}

static int __init xen_iommu_init(void)
Expand Down
3 changes: 2 additions & 1 deletion include/xen/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

struct pci_dev;

#if defined(CONFIG_XEN_PCIDEV_FRONTEND)
/* Called from built-in code, so a modular pcifront is as good as none. */
#if IS_BUILTIN(CONFIG_XEN_PCIDEV_FRONTEND)
int pcifront_machine_sbdf(const struct pci_dev *dev, u32 *sbdf);
#else
static inline int pcifront_machine_sbdf(const struct pci_dev *dev, u32 *sbdf)
Expand Down
Loading