mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 15:42:46 +00:00
iommu/vt-d: Add blocking domain support
The Intel IOMMU hardwares support blocking DMA transactions by clearing the translation table entries. This implements a real blocking domain to avoid using an empty UNMANAGED domain. The detach_dev callback of the domain ops is not used in any path. Remove it to avoid dead code as well. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Link: https://lore.kernel.org/r/20221118132451.114406-4-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
c7be17c290
commit
35a99c54dd
1 changed files with 18 additions and 8 deletions
|
@ -278,6 +278,7 @@ static LIST_HEAD(dmar_satc_units);
|
|||
list_for_each_entry(rmrr, &dmar_rmrr_units, list)
|
||||
|
||||
static void device_block_translation(struct device *dev);
|
||||
static void intel_iommu_domain_free(struct iommu_domain *domain);
|
||||
|
||||
int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
|
||||
int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
|
||||
|
@ -4162,12 +4163,28 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int blocking_domain_attach_dev(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
device_block_translation(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct iommu_domain blocking_domain = {
|
||||
.ops = &(const struct iommu_domain_ops) {
|
||||
.attach_dev = blocking_domain_attach_dev,
|
||||
.free = intel_iommu_domain_free
|
||||
}
|
||||
};
|
||||
|
||||
static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
|
||||
{
|
||||
struct dmar_domain *dmar_domain;
|
||||
struct iommu_domain *domain;
|
||||
|
||||
switch (type) {
|
||||
case IOMMU_DOMAIN_BLOCKED:
|
||||
return &blocking_domain;
|
||||
case IOMMU_DOMAIN_DMA:
|
||||
case IOMMU_DOMAIN_DMA_FQ:
|
||||
case IOMMU_DOMAIN_UNMANAGED:
|
||||
|
@ -4200,7 +4217,7 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
|
|||
|
||||
static void intel_iommu_domain_free(struct iommu_domain *domain)
|
||||
{
|
||||
if (domain != &si_domain->domain)
|
||||
if (domain != &si_domain->domain && domain != &blocking_domain)
|
||||
domain_exit(to_dmar_domain(domain));
|
||||
}
|
||||
|
||||
|
@ -4274,12 +4291,6 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
|
|||
return domain_add_dev_info(to_dmar_domain(domain), dev);
|
||||
}
|
||||
|
||||
static void intel_iommu_detach_device(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
dmar_remove_one_dev_info(dev);
|
||||
}
|
||||
|
||||
static int intel_iommu_map(struct iommu_domain *domain,
|
||||
unsigned long iova, phys_addr_t hpa,
|
||||
size_t size, int iommu_prot, gfp_t gfp)
|
||||
|
@ -4767,7 +4778,6 @@ const struct iommu_ops intel_iommu_ops = {
|
|||
#endif
|
||||
.default_domain_ops = &(const struct iommu_domain_ops) {
|
||||
.attach_dev = intel_iommu_attach_device,
|
||||
.detach_dev = intel_iommu_detach_device,
|
||||
.map_pages = intel_iommu_map_pages,
|
||||
.unmap_pages = intel_iommu_unmap_pages,
|
||||
.iotlb_sync_map = intel_iommu_iotlb_sync_map,
|
||||
|
|
Loading…
Reference in a new issue