else
domid = domain->id;
++++++++ make_clear_dte(dev_data, dte, &new);
++++++++
if (domain->iop.mode != PAGE_MODE_NONE)
-------- pte_root = iommu_virt_to_phys(domain->iop.root);
++++++++ new.data[0] = iommu_virt_to_phys(domain->iop.root);
-------- pte_root |= (domain->iop.mode & DEV_ENTRY_MODE_MASK)
++++++++ new.data[0] |= (domain->iop.mode & DEV_ENTRY_MODE_MASK)
<< DEV_ENTRY_MODE_SHIFT;
-------- pte_root |= DTE_FLAG_IR | DTE_FLAG_IW | DTE_FLAG_V;
++++++++ new.data[0] |= DTE_FLAG_IR | DTE_FLAG_IW | DTE_FLAG_V;
/*
-------- * When SNP is enabled, Only set TV bit when IOMMU
-------- * page translation is in use.
++++++++ * When SNP is enabled, we can only support TV=1 with non-zero domain ID.
++++++++ * This is prevented by the SNP-enable and IOMMU_DOMAIN_IDENTITY check in
++++++++ * do_iommu_domain_alloc().
*/
-------- if (!amd_iommu_snp_en || (domid != 0))
-------- pte_root |= DTE_FLAG_TV;
--------
-------- flags = dev_table[devid].data[1];
--------
-------- if (dev_data->ats_enabled)
-------- flags |= DTE_FLAG_IOTLB;
++++++++ WARN_ON(amd_iommu_snp_en && (domid == 0));
++++++++ new.data[0] |= DTE_FLAG_TV;
if (dev_data->ppr)
-------- pte_root |= 1ULL << DEV_ENTRY_PPR;
++++++++ new.data[0] |= 1ULL << DEV_ENTRY_PPR;
if (domain->dirty_tracking)
-------- pte_root |= DTE_FLAG_HAD;
--------
-------- if (gcr3_info && gcr3_info->gcr3_tbl) {
-------- u64 gcr3 = iommu_virt_to_phys(gcr3_info->gcr3_tbl);
-------- u64 glx = gcr3_info->glx;
-------- u64 tmp;
-- -
-- - pte_root |= DTE_FLAG_GV;
-- - pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT;
-
- /* First mask out possible old values for GCR3 table */
- tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B;
- flags &= ~tmp;
++++++++ new.data[0] |= DTE_FLAG_HAD;
- --- - pte_root |= DTE_FLAG_GV;
- --- - pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT;
- --- -
------ - /* First mask out possible old values for GCR3 table */
------ - tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B;
------ - flags &= ~tmp;
------ -
-------- tmp = DTE_GCR3_VAL_C(~0ULL) << DTE_GCR3_SHIFT_C;
-------- flags &= ~tmp;
--------
-------- /* Encode GCR3 table into DTE */
-------- tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A;
-------- pte_root |= tmp;
--------
-------- tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B;
-------- flags |= tmp;
--------
-------- tmp = DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C;
-------- flags |= tmp;
++++++++ if (dev_data->ats_enabled)
++++++++ new.data[1] |= DTE_FLAG_IOTLB;
-------- if (amd_iommu_gpt_level == PAGE_MODE_5_LEVEL) {
-------- dev_table[devid].data[2] |=
-------- ((u64)GUEST_PGTABLE_5_LEVEL << DTE_GPT_LEVEL_SHIFT);
-------- }
++++++++ old_domid = READ_ONCE(dte->data[1]) & DEV_DOMID_MASK;
++++++++ new.data[1] |= domid;
-------- /* GIOV is supported with V2 page table mode only */
-------- if (pdom_is_v2_pgtbl_mode(domain))
-------- pte_root |= DTE_FLAG_GIOV;
++++++++ /*
++++++++ * Restore cached persistent DTE bits, which can be set by information
++++++++ * in IVRS table. See set_dev_entry_from_acpi().
++++++++ */
++++++++ initial_dte = amd_iommu_get_ivhd_dte_flags(iommu->pci_seg->id, dev_data->devid);
++++++++ if (initial_dte) {
++++++++ new.data128[0] |= initial_dte->data128[0];
++++++++ new.data128[1] |= initial_dte->data128[1];
}
-------- flags &= ~DEV_DOMID_MASK;
-------- flags |= domid;
++++++++ set_dte_gcr3_table(iommu, dev_data, &new);
-------- old_domid = dev_table[devid].data[1] & DEV_DOMID_MASK;
-------- dev_table[devid].data[1] = flags;
-------- dev_table[devid].data[0] = pte_root;
++++++++ update_dte256(iommu, dev_data, &new);
/*
* A kdump kernel might be replacing a domain ID that was copied from
}
}
-------- static void clear_dte_entry(struct amd_iommu *iommu, u16 devid)
++++++++ /*
++++++++ * Clear DMA-remap related flags to block all DMA (blockeded domain)
++++++++ */
++++++++ static void clear_dte_entry(struct amd_iommu *iommu, struct iommu_dev_data *dev_data)
{
-------- struct dev_table_entry *dev_table = get_dev_table(iommu);
- --- -
- --- - /* remove entry from the device table seen by the hardware */
- --- - dev_table[devid].data[0] = DTE_FLAG_V;
- --- -
- --- - if (!amd_iommu_snp_en)
- --- - dev_table[devid].data[0] |= DTE_FLAG_TV;
++++++++ struct dev_table_entry new = {};
++++++++ struct dev_table_entry *dte = &get_dev_table(iommu)[dev_data->devid];
-- - /* remove entry from the device table seen by the hardware */
-- - dev_table[devid].data[0] = DTE_FLAG_V;
-- -
-- - if (!amd_iommu_snp_en)
-- - dev_table[devid].data[0] |= DTE_FLAG_TV;
-- -
-------- dev_table[devid].data[1] &= DTE_FLAG_MASK;
--------
-------- amd_iommu_apply_erratum_63(iommu, devid);
++++++++ make_clear_dte(dev_data, dte, &new);
++++++++ update_dte256(iommu, dev_data, &new);
}
/* Update and flush DTE for the given device */