if ( !dt )
{
+ unsigned int size = dt_alloc_size();
+
/* allocate 'device table' on a 4K boundary */
dt = IVRS_MAPPINGS_DEVTAB(ivrs_mappings) =
- allocate_buffer(dt_alloc_size(), "Device Table", true);
+ allocate_buffer(size, "Device Table", false);
+ if ( !dt )
+ return -ENOMEM;
+
+ /*
+ * Prefill every DTE such that all kinds of requests will get aborted.
+ * Besides the two bits set to true below this builds upon
+ * IOMMU_DEV_TABLE_SYS_MGT_DMA_ABORTED,
+ * IOMMU_DEV_TABLE_IO_CONTROL_ABORTED, as well as
+ * IOMMU_DEV_TABLE_INT_CONTROL_ABORTED all being zero, and us also
+ * wanting at least TV, GV, I, and EX set to false.
+ */
+ for ( bdf = 0, size /= sizeof(*dt); bdf < size; ++bdf )
+ dt[bdf] = (struct amd_iommu_dte){
+ .v = true,
+ .iv = true,
+ };
}
- if ( !dt )
- return -ENOMEM;
/* Add device table entries */
for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ )
setup_hwdom_pci_devices(d, amd_iommu_add_device);
}
-void amd_iommu_disable_domain_device(struct domain *domain,
- struct amd_iommu *iommu,
- u8 devfn, struct pci_dev *pdev)
+static void amd_iommu_disable_domain_device(const struct domain *domain,
+ struct amd_iommu *iommu,
+ uint8_t devfn, struct pci_dev *pdev)
{
struct amd_iommu_dte *table, *dte;
unsigned long flags;
spin_lock_irqsave(&iommu->lock, flags);
if ( dte->tv || dte->v )
{
+ /* See the comment in amd_iommu_setup_device_table(). */
+ dte->int_ctl = IOMMU_DEV_TABLE_INT_CONTROL_ABORTED;
+ smp_wmb();
+ dte->iv = true;
dte->tv = false;
- dte->v = false;
+ dte->gv = false;
dte->i = false;
+ dte->ex = false;
+ dte->sa = false;
+ dte->se = false;
+ dte->sd = false;
+ dte->sys_mgt = IOMMU_DEV_TABLE_SYS_MGT_DMA_ABORTED;
+ dte->ioctl = IOMMU_DEV_TABLE_IO_CONTROL_ABORTED;
+ smp_wmb();
+ dte->v = true;
amd_iommu_flush_device(iommu, req_id);