Commit 010bf565 authored by Kyung Min Park's avatar Kyung Min Park Committed by Joerg Roedel
Browse files

iommu/vt-d: Move capability check code to cap_audit files



Move IOMMU capability check and sanity check code to cap_audit files.
Also implement some helper functions for sanity checks.

Signed-off-by: default avatarKyung Min Park <kyung.min.park@intel.com>
Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20210130184452.31711-1-kyung.min.park@intel.com
Link: https://lore.kernel.org/r/20210204014401.2846425-4-baolu.lu@linux.intel.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent ad3d1902
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -183,3 +183,23 @@ int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu)

	return -EFAULT;
}

bool intel_cap_smts_sanity(void)
{
	return ecap_smts(intel_iommu_ecap_sanity);
}

bool intel_cap_pasid_sanity(void)
{
	return ecap_pasid(intel_iommu_ecap_sanity);
}

bool intel_cap_nest_sanity(void)
{
	return ecap_nest(intel_iommu_ecap_sanity);
}

bool intel_cap_flts_sanity(void)
{
	return ecap_flts(intel_iommu_ecap_sanity);
}
+20 −0
Original line number Diff line number Diff line
@@ -107,4 +107,24 @@ enum cap_audit_type {
	CAP_AUDIT_HOTPLUG_IRQR,
};

bool intel_cap_smts_sanity(void);
bool intel_cap_pasid_sanity(void);
bool intel_cap_nest_sanity(void);
bool intel_cap_flts_sanity(void);

static inline bool scalable_mode_support(void)
{
	return (intel_iommu_sm && intel_cap_smts_sanity());
}

static inline bool pasid_mode_support(void)
{
	return scalable_mode_support() && intel_cap_pasid_sanity();
}

static inline bool nested_mode_support(void)
{
	return scalable_mode_support() && intel_cap_nest_sanity();
}

int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu);
+2 −74
Original line number Diff line number Diff line
@@ -1864,25 +1864,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
 */
static bool first_level_by_default(void)
{
	struct dmar_drhd_unit *drhd;
	struct intel_iommu *iommu;
	static int first_level_support = -1;

	if (likely(first_level_support != -1))
		return first_level_support;

	first_level_support = 1;

	rcu_read_lock();
	for_each_active_iommu(iommu, drhd) {
		if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) {
			first_level_support = 0;
			break;
		}
	}
	rcu_read_unlock();

	return first_level_support;
	return scalable_mode_support() && intel_cap_flts_sanity();
}

static struct dmar_domain *alloc_domain(int flags)
@@ -5058,60 +5040,6 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
	return phys;
}

static inline bool scalable_mode_support(void)
{
	struct dmar_drhd_unit *drhd;
	struct intel_iommu *iommu;
	bool ret = true;

	rcu_read_lock();
	for_each_active_iommu(iommu, drhd) {
		if (!sm_supported(iommu)) {
			ret = false;
			break;
		}
	}
	rcu_read_unlock();

	return ret;
}

static inline bool iommu_pasid_support(void)
{
	struct dmar_drhd_unit *drhd;
	struct intel_iommu *iommu;
	bool ret = true;

	rcu_read_lock();
	for_each_active_iommu(iommu, drhd) {
		if (!pasid_supported(iommu)) {
			ret = false;
			break;
		}
	}
	rcu_read_unlock();

	return ret;
}

static inline bool nested_mode_support(void)
{
	struct dmar_drhd_unit *drhd;
	struct intel_iommu *iommu;
	bool ret = true;

	rcu_read_lock();
	for_each_active_iommu(iommu, drhd) {
		if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
			ret = false;
			break;
		}
	}
	rcu_read_unlock();

	return ret;
}

static bool intel_iommu_capable(enum iommu_cap cap)
{
	if (cap == IOMMU_CAP_CACHE_COHERENCY)
@@ -5352,7 +5280,7 @@ intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)
		int ret;

		if (!dev_is_pci(dev) || dmar_disabled ||
		    !scalable_mode_support() || !iommu_pasid_support())
		    !scalable_mode_support() || !pasid_mode_support())
			return false;

		ret = pci_pasid_features(to_pci_dev(dev));