IOMMU Fixes for Linux v5.14-rc1
Including: - Revert a patch which caused boot failures with QCOM IOMMU - Two fixes for Intel VT-d context table handling - Physical address decoding fix for Rockchip IOMMU - Add a reviewer for AMD IOMMU -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEr9jSbILcajRFYWYyK/BELZcBGuMFAmDv7NwACgkQK/BELZcB GuPu4hAA4vBoPD9fyO1U96tRu3tFchLIF/BmmOo9PWTcCAZ1MzcI35aHxKUZBApa HLsLRiH/knTrGwTcHwPMOjyDfWb/PuM00/x43FwNn/0wIjsw0Bp/jfXgTIzoQnkZ 7QVYNvDt7TWor19kfVLCjdlBwJAr26wXjUUCODq53OHJXMXlrA8Fj1XSC4St0SsL MAkowvOXJO/Ibly9jjoxnjkbXw7v0I2TklH+oM3zdo+GaLozSTztkwqbJ6zicZee AoITGjpVk69VGKbHOR+WJeeJIU9thIWisFL1HkWO4EWh+Ze2rmzVzjdBfXLABYL0 T1DFiQdpPN1+WsWxcoA15UOnSJtrLc+VjZi7/ncRXCyWyZZjOMLWVomgT3fXDwqw 8rUJAYKARALeBA8fSMnPjuzzPGXPhIw0RQXsd7VyGBYMRHhSzj1NRBsdgFl+vcb6 +FixorSsQx0C2w7/m/qF4INzxP/r7B4n+yL2m+nIYzmGJLngTE7yIdFsslHu2r5G etiQCtoptpp+LlvRNuA4YxJkxrtYHQN3YyVK4gL3SG59QZmuMcvVkomsTUHM92HN L8fhfcBQwG8Gpcjovm6isMkqEmunfb3LwiJj2/RHnlGf8mvVjHV9vzaW3DFB0ieB +reRv4T52VDoYPdiv5irDV8J19Z/HMv8+AkoR1GHt7G4uNutFk4= =l9Jd -----END PGP SIGNATURE----- Merge tag 'iommu-fixes-v5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull iommu fixes from Joerg Roedel: - Revert a patch which caused boot failures with QCOM IOMMU - Two fixes for Intel VT-d context table handling - Physical address decoding fix for Rockchip IOMMU - Add a reviewer for AMD IOMMU * tag 'iommu-fixes-v5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: MAINTAINERS: Add Suravee Suthikulpanit as Reviewer for AMD IOMMU (AMD-Vi) iommu/rockchip: Fix physical address decoding iommu/vt-d: Fix clearing real DMA device's scalable-mode context entries iommu/vt-d: Global devTLB flush when present context entry changed iommu/qcom: Revert "iommu/arm: Cleanup resources in case of probe error path"
This commit is contained in:
commit
f3523a226d
@ -933,6 +933,7 @@ F: drivers/video/fbdev/geode/
|
|||||||
|
|
||||||
AMD IOMMU (AMD-VI)
|
AMD IOMMU (AMD-VI)
|
||||||
M: Joerg Roedel <joro@8bytes.org>
|
M: Joerg Roedel <joro@8bytes.org>
|
||||||
|
R: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
|
||||||
L: iommu@lists.linux-foundation.org
|
L: iommu@lists.linux-foundation.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
|
||||||
|
@ -849,12 +849,10 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
|
|||||||
ret = iommu_device_register(&qcom_iommu->iommu, &qcom_iommu_ops, dev);
|
ret = iommu_device_register(&qcom_iommu->iommu, &qcom_iommu_ops, dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "Failed to register iommu\n");
|
dev_err(dev, "Failed to register iommu\n");
|
||||||
goto err_sysfs_remove;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bus_set_iommu(&platform_bus_type, &qcom_iommu_ops);
|
bus_set_iommu(&platform_bus_type, &qcom_iommu_ops);
|
||||||
if (ret)
|
|
||||||
goto err_unregister_device;
|
|
||||||
|
|
||||||
if (qcom_iommu->local_base) {
|
if (qcom_iommu->local_base) {
|
||||||
pm_runtime_get_sync(dev);
|
pm_runtime_get_sync(dev);
|
||||||
@ -863,13 +861,6 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_unregister_device:
|
|
||||||
iommu_device_unregister(&qcom_iommu->iommu);
|
|
||||||
|
|
||||||
err_sysfs_remove:
|
|
||||||
iommu_device_sysfs_remove(&qcom_iommu->iommu);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcom_iommu_device_remove(struct platform_device *pdev)
|
static int qcom_iommu_device_remove(struct platform_device *pdev)
|
||||||
|
@ -2429,10 +2429,11 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
|
static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8 devfn)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
struct intel_iommu *iommu = info->iommu;
|
||||||
struct context_entry *context;
|
struct context_entry *context;
|
||||||
|
unsigned long flags;
|
||||||
u16 did_old;
|
u16 did_old;
|
||||||
|
|
||||||
if (!iommu)
|
if (!iommu)
|
||||||
@ -2444,7 +2445,16 @@ static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn
|
|||||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
did_old = context_domain_id(context);
|
|
||||||
|
if (sm_supported(iommu)) {
|
||||||
|
if (hw_pass_through && domain_type_is_si(info->domain))
|
||||||
|
did_old = FLPT_DEFAULT_DID;
|
||||||
|
else
|
||||||
|
did_old = info->domain->iommu_did[iommu->seq_id];
|
||||||
|
} else {
|
||||||
|
did_old = context_domain_id(context);
|
||||||
|
}
|
||||||
|
|
||||||
context_clear_entry(context);
|
context_clear_entry(context);
|
||||||
__iommu_flush_cache(iommu, context, sizeof(*context));
|
__iommu_flush_cache(iommu, context, sizeof(*context));
|
||||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||||
@ -2462,6 +2472,8 @@ static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
DMA_TLB_DSI_FLUSH);
|
DMA_TLB_DSI_FLUSH);
|
||||||
|
|
||||||
|
__iommu_flush_dev_iotlb(info, 0, MAX_AGAW_PFN_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void unlink_domain_info(struct device_domain_info *info)
|
static inline void unlink_domain_info(struct device_domain_info *info)
|
||||||
@ -4425,9 +4437,9 @@ out_free_dmar:
|
|||||||
|
|
||||||
static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
|
static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
|
||||||
{
|
{
|
||||||
struct intel_iommu *iommu = opaque;
|
struct device_domain_info *info = opaque;
|
||||||
|
|
||||||
domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
|
domain_context_clear_one(info, PCI_BUS_NUM(alias), alias & 0xff);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4437,12 +4449,13 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op
|
|||||||
* devices, unbinding the driver from any one of them will possibly leave
|
* devices, unbinding the driver from any one of them will possibly leave
|
||||||
* the others unable to operate.
|
* the others unable to operate.
|
||||||
*/
|
*/
|
||||||
static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
|
static void domain_context_clear(struct device_domain_info *info)
|
||||||
{
|
{
|
||||||
if (!iommu || !dev || !dev_is_pci(dev))
|
if (!info->iommu || !info->dev || !dev_is_pci(info->dev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
|
pci_for_each_dma_alias(to_pci_dev(info->dev),
|
||||||
|
&domain_context_clear_one_cb, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __dmar_remove_one_dev_info(struct device_domain_info *info)
|
static void __dmar_remove_one_dev_info(struct device_domain_info *info)
|
||||||
@ -4459,14 +4472,13 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
|
|||||||
iommu = info->iommu;
|
iommu = info->iommu;
|
||||||
domain = info->domain;
|
domain = info->domain;
|
||||||
|
|
||||||
if (info->dev) {
|
if (info->dev && !dev_is_real_dma_subdevice(info->dev)) {
|
||||||
if (dev_is_pci(info->dev) && sm_supported(iommu))
|
if (dev_is_pci(info->dev) && sm_supported(iommu))
|
||||||
intel_pasid_tear_down_entry(iommu, info->dev,
|
intel_pasid_tear_down_entry(iommu, info->dev,
|
||||||
PASID_RID2PASID, false);
|
PASID_RID2PASID, false);
|
||||||
|
|
||||||
iommu_disable_dev_iotlb(info);
|
iommu_disable_dev_iotlb(info);
|
||||||
if (!dev_is_real_dma_subdevice(info->dev))
|
domain_context_clear(info);
|
||||||
domain_context_clear(iommu, info->dev);
|
|
||||||
intel_pasid_free_table(info->dev);
|
intel_pasid_free_table(info->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,12 +544,14 @@ static inline u32 rk_dma_addr_dte(dma_addr_t dt_dma)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define DT_HI_MASK GENMASK_ULL(39, 32)
|
#define DT_HI_MASK GENMASK_ULL(39, 32)
|
||||||
|
#define DTE_BASE_HI_MASK GENMASK(11, 4)
|
||||||
#define DT_SHIFT 28
|
#define DT_SHIFT 28
|
||||||
|
|
||||||
static inline phys_addr_t rk_dte_addr_phys_v2(u32 addr)
|
static inline phys_addr_t rk_dte_addr_phys_v2(u32 addr)
|
||||||
{
|
{
|
||||||
return (phys_addr_t)(addr & RK_DTE_PT_ADDRESS_MASK) |
|
u64 addr64 = addr;
|
||||||
((addr & DT_HI_MASK) << DT_SHIFT);
|
return (phys_addr_t)(addr64 & RK_DTE_PT_ADDRESS_MASK) |
|
||||||
|
((addr64 & DTE_BASE_HI_MASK) << DT_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 rk_dma_addr_dte_v2(dma_addr_t dt_dma)
|
static inline u32 rk_dma_addr_dte_v2(dma_addr_t dt_dma)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user