diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-11-06 12:48:19 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-11-06 12:48:19 -0800 |
commit | 02a2aa3500a993c9f0812b8564d36d63b8d49ce4 (patch) | |
tree | 60643efe4a5c10d7c832e79556bcb1f233be8a91 | |
parent | 1669ecf9c884c639c4a83859e33a24d892aec790 (diff) | |
parent | 4dd6ce478003525df8618750d30f0b90380047a7 (diff) | |
download | lwn-02a2aa3500a993c9f0812b8564d36d63b8d49ce4.tar.gz lwn-02a2aa3500a993c9f0812b8564d36d63b8d49ce4.zip |
Merge tag 'iommu-fixes-v5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel:
- Fix a NULL-ptr dereference in the Intel VT-d driver
- Two fixes for Intel SVM support
- Increase IRQ remapping table size in the AMD IOMMU driver. The old
number of 128 turned out to be too low for some recent devices.
- Fix a mask check in generic IOMMU code
* tag 'iommu-fixes-v5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
iommu: Fix a check in iommu_check_bind_data()
iommu/vt-d: Fix a bug for PDP check in prq_event_thread
iommu/vt-d: Fix sid not set issue in intel_svm_bind_gpasid()
iommu/vt-d: Fix kernel NULL pointer dereference in find_domain()
iommu/amd: Increase interrupt remapping table limit to 512 entries
-rw-r--r-- | drivers/iommu/amd/amd_iommu_types.h | 6 | ||||
-rw-r--r-- | drivers/iommu/intel/iommu.c | 3 | ||||
-rw-r--r-- | drivers/iommu/intel/svm.c | 8 | ||||
-rw-r--r-- | drivers/iommu/iommu.c | 2 |
4 files changed, 16 insertions, 3 deletions
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index f696ac7c5f89..89647700bab2 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -409,7 +409,11 @@ extern bool amd_iommu_np_cache; /* Only true if all IOMMUs support device IOTLBs */ extern bool amd_iommu_iotlb_sup; -#define MAX_IRQS_PER_TABLE 256 +/* + * AMD IOMMU hardware only support 512 IRTEs despite + * the architectural limitation of 2048 entries. + */ +#define MAX_IRQS_PER_TABLE 512 #define IRQ_TABLE_ALIGNMENT 128 struct irq_remap_table { diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 8651f6d4dfa0..1b1ca63e6bbe 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2525,6 +2525,9 @@ struct dmar_domain *find_domain(struct device *dev) { struct device_domain_info *info; + if (unlikely(!dev || !dev->iommu)) + return NULL; + if (unlikely(attach_deferred(dev))) return NULL; diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index f1861fa3d0e4..3242ebd0bca3 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -279,6 +279,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL); struct intel_svm_dev *sdev = NULL; struct dmar_domain *dmar_domain; + struct device_domain_info *info; struct intel_svm *svm = NULL; int ret = 0; @@ -310,6 +311,10 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, if (data->hpasid <= 0 || data->hpasid >= PASID_MAX) return -EINVAL; + info = get_domain_info(dev); + if (!info) + return -EINVAL; + dmar_domain = to_dmar_domain(domain); mutex_lock(&pasid_mutex); @@ -357,6 +362,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, goto out; } sdev->dev = dev; + sdev->sid = PCI_DEVID(info->bus, info->devfn); /* Only count users if device has aux domains */ if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)) @@ -1029,7 +1035,7 @@ no_pasid: resp.qw0 = QI_PGRP_PASID(req->pasid) | QI_PGRP_DID(req->rid) | QI_PGRP_PASID_P(req->pasid_present) | - QI_PGRP_PDP(req->pasid_present) | + QI_PGRP_PDP(req->priv_data_present) | QI_PGRP_RESP_CODE(result) | QI_PGRP_RESP_TYPE; resp.qw1 = QI_PGRP_IDX(req->prg_index) | diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 8c470f451a32..b53446bb8c6b 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2071,7 +2071,7 @@ EXPORT_SYMBOL_GPL(iommu_uapi_cache_invalidate); static int iommu_check_bind_data(struct iommu_gpasid_bind_data *data) { - u32 mask; + u64 mask; int i; if (data->version != IOMMU_GPASID_BIND_VERSION_1) |