Commit 02a2aa35 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 1669ecf9 4dd6ce47
...@@ -409,7 +409,11 @@ extern bool amd_iommu_np_cache; ...@@ -409,7 +409,11 @@ extern bool amd_iommu_np_cache;
/* Only true if all IOMMUs support device IOTLBs */ /* Only true if all IOMMUs support device IOTLBs */
extern bool amd_iommu_iotlb_sup; 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 #define IRQ_TABLE_ALIGNMENT 128
struct irq_remap_table { struct irq_remap_table {
......
...@@ -2525,6 +2525,9 @@ struct dmar_domain *find_domain(struct device *dev) ...@@ -2525,6 +2525,9 @@ struct dmar_domain *find_domain(struct device *dev)
{ {
struct device_domain_info *info; struct device_domain_info *info;
if (unlikely(!dev || !dev->iommu))
return NULL;
if (unlikely(attach_deferred(dev))) if (unlikely(attach_deferred(dev)))
return NULL; return NULL;
......
...@@ -279,6 +279,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, ...@@ -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_iommu *iommu = device_to_iommu(dev, NULL, NULL);
struct intel_svm_dev *sdev = NULL; struct intel_svm_dev *sdev = NULL;
struct dmar_domain *dmar_domain; struct dmar_domain *dmar_domain;
struct device_domain_info *info;
struct intel_svm *svm = NULL; struct intel_svm *svm = NULL;
int ret = 0; int ret = 0;
...@@ -310,6 +311,10 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, ...@@ -310,6 +311,10 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev,
if (data->hpasid <= 0 || data->hpasid >= PASID_MAX) if (data->hpasid <= 0 || data->hpasid >= PASID_MAX)
return -EINVAL; return -EINVAL;
info = get_domain_info(dev);
if (!info)
return -EINVAL;
dmar_domain = to_dmar_domain(domain); dmar_domain = to_dmar_domain(domain);
mutex_lock(&pasid_mutex); mutex_lock(&pasid_mutex);
...@@ -357,6 +362,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, ...@@ -357,6 +362,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev,
goto out; goto out;
} }
sdev->dev = dev; sdev->dev = dev;
sdev->sid = PCI_DEVID(info->bus, info->devfn);
/* Only count users if device has aux domains */ /* Only count users if device has aux domains */
if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)) if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX))
...@@ -1029,7 +1035,7 @@ static irqreturn_t prq_event_thread(int irq, void *d) ...@@ -1029,7 +1035,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
resp.qw0 = QI_PGRP_PASID(req->pasid) | resp.qw0 = QI_PGRP_PASID(req->pasid) |
QI_PGRP_DID(req->rid) | QI_PGRP_DID(req->rid) |
QI_PGRP_PASID_P(req->pasid_present) | 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_CODE(result) |
QI_PGRP_RESP_TYPE; QI_PGRP_RESP_TYPE;
resp.qw1 = QI_PGRP_IDX(req->prg_index) | resp.qw1 = QI_PGRP_IDX(req->prg_index) |
......
...@@ -2071,7 +2071,7 @@ EXPORT_SYMBOL_GPL(iommu_uapi_cache_invalidate); ...@@ -2071,7 +2071,7 @@ EXPORT_SYMBOL_GPL(iommu_uapi_cache_invalidate);
static int iommu_check_bind_data(struct iommu_gpasid_bind_data *data) static int iommu_check_bind_data(struct iommu_gpasid_bind_data *data)
{ {
u32 mask; u64 mask;
int i; int i;
if (data->version != IOMMU_GPASID_BIND_VERSION_1) if (data->version != IOMMU_GPASID_BIND_VERSION_1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment