]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iommu/vt-d: Don't read VCCAP register unless it exists
authorDavid Woodhouse <dwmw@amazon.co.uk>
Thu, 26 Nov 2020 11:13:51 +0000 (11:13 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Dec 2020 07:51:46 +0000 (08:51 +0100)
commit d76b42e92780c3587c1a998a3a943b501c137553 upstream.

My virtual IOMMU implementation is whining that the guest is reading a
register that doesn't exist. Only read the VCCAP_REG if the corresponding
capability is set in ECAP_REG to indicate that it actually exists.

Fixes: 3375303e8287 ("iommu/vt-d: Add custom allocator for IOASID")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Liu Yi L <yi.l.liu@intel.com>
Cc: stable@vger.kernel.org # v5.7+
Acked-by: Lu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/de32b150ffaa752e0cff8571b17dfb1213fbe71c.camel@infradead.org
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/iommu/intel/dmar.c
drivers/iommu/intel/iommu.c

index 93e6345f3414f08395b6837797f67101444ac897..48cda86f43a2cec45e696f55400d000f6e1dfa5c 100644 (file)
@@ -964,7 +964,8 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr)
                warn_invalid_dmar(phys_addr, " returns all ones");
                goto unmap;
        }
-       iommu->vccap = dmar_readq(iommu->reg + DMAR_VCCAP_REG);
+       if (ecap_vcs(iommu->ecap))
+               iommu->vccap = dmar_readq(iommu->reg + DMAR_VCCAP_REG);
 
        /* the registers might be more than one page */
        map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
index f67b7e6ddf1bcdf07a92bf4a9d3359a130ab9367..7e790655c1ab5f6a6fff6ac4028eac266ff923f5 100644 (file)
@@ -1798,7 +1798,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
                if (ecap_prs(iommu->ecap))
                        intel_svm_finish_prq(iommu);
        }
-       if (ecap_vcs(iommu->ecap) && vccap_pasid(iommu->vccap))
+       if (vccap_pasid(iommu->vccap))
                ioasid_unregister_allocator(&iommu->pasid_allocator);
 
 #endif
@@ -3177,7 +3177,7 @@ static void register_pasid_allocator(struct intel_iommu *iommu)
         * is active. All vIOMMU allocators will eventually be calling the same
         * host allocator.
         */
-       if (!ecap_vcs(iommu->ecap) || !vccap_pasid(iommu->vccap))
+       if (!vccap_pasid(iommu->vccap))
                return;
 
        pr_info("Register custom PASID allocator\n");