mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-27 22:28:25 -04:00
Merge tag 'iommu-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull iommu fixes from Will Deacon: "Three IOMMU fixes for -rc4. The main one is a change to the Intel IOMMU driver to fix the handling of unaligned addresses when invalidating the TLB. The fix itself is a bit ugly (the caller does a bunch of shifting which is then effectively undone later in the callchain), but Lu has patches to clean all of this up in 5.12. Summary: - Fix address alignment handling for VT-D TLB invalidation - Enable workarounds for buggy Qualcomm firmware on two more SoCs - Drop duplicate #include" * tag 'iommu-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: iommu/vt-d: Fix duplicate included linux/dma-map-ops.h iommu: arm-smmu-qcom: Add sdm630/msm8998 compatibles for qcom quirks iommu/vt-d: Fix unaligned addresses for intel_flush_svm_range_dev()
This commit is contained in:
@@ -325,7 +325,9 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
|
||||
}
|
||||
|
||||
static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = {
|
||||
{ .compatible = "qcom,msm8998-smmu-v2" },
|
||||
{ .compatible = "qcom,sc7180-smmu-500" },
|
||||
{ .compatible = "qcom,sdm630-smmu-v2" },
|
||||
{ .compatible = "qcom,sdm845-smmu-500" },
|
||||
{ .compatible = "qcom,sm8150-smmu-500" },
|
||||
{ .compatible = "qcom,sm8250-smmu-500" },
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/pci-ats.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/dma-map-ops.h>
|
||||
#include <linux/dma-direct.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/numa.h>
|
||||
|
||||
@@ -118,8 +118,10 @@ void intel_svm_check(struct intel_iommu *iommu)
|
||||
iommu->flags |= VTD_FLAG_SVM_CAPABLE;
|
||||
}
|
||||
|
||||
static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev,
|
||||
unsigned long address, unsigned long pages, int ih)
|
||||
static void __flush_svm_range_dev(struct intel_svm *svm,
|
||||
struct intel_svm_dev *sdev,
|
||||
unsigned long address,
|
||||
unsigned long pages, int ih)
|
||||
{
|
||||
struct qi_desc desc;
|
||||
|
||||
@@ -170,6 +172,22 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_flush_svm_range_dev(struct intel_svm *svm,
|
||||
struct intel_svm_dev *sdev,
|
||||
unsigned long address,
|
||||
unsigned long pages, int ih)
|
||||
{
|
||||
unsigned long shift = ilog2(__roundup_pow_of_two(pages));
|
||||
unsigned long align = (1ULL << (VTD_PAGE_SHIFT + shift));
|
||||
unsigned long start = ALIGN_DOWN(address, align);
|
||||
unsigned long end = ALIGN(address + (pages << VTD_PAGE_SHIFT), align);
|
||||
|
||||
while (start < end) {
|
||||
__flush_svm_range_dev(svm, sdev, start, align >> VTD_PAGE_SHIFT, ih);
|
||||
start += align;
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address,
|
||||
unsigned long pages, int ih)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user