| From d76b42e92780c3587c1a998a3a943b501c137553 Mon Sep 17 00:00:00 2001 |
| From: David Woodhouse <dwmw@amazon.co.uk> |
| Date: Thu, 26 Nov 2020 11:13:51 +0000 |
| Subject: iommu/vt-d: Don't read VCCAP register unless it exists |
| |
| From: David Woodhouse <dwmw@amazon.co.uk> |
| |
| 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 | 3 ++- |
| drivers/iommu/intel/iommu.c | 4 ++-- |
| 2 files changed, 4 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/iommu/intel/dmar.c |
| +++ b/drivers/iommu/intel/dmar.c |
| @@ -964,7 +964,8 @@ static int map_iommu(struct intel_iommu |
| 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), |
| --- a/drivers/iommu/intel/iommu.c |
| +++ b/drivers/iommu/intel/iommu.c |
| @@ -1798,7 +1798,7 @@ static void free_dmar_iommu(struct intel |
| 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(str |
| * 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"); |