mirror of https://gitee.com/openkylin/linux.git
IOMMU Fixes for Linux v4.12-rc4
Including: * Another compile-fix for my header cleanup * A couple of fixes for the recently merged IOMMU probe deferal code * Includes fixes for ACPI/IORT code necessary with IOMMU probe deferal -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJZOyKuAAoJECvwRC2XARrjb1EP/iM+5lHWikgAZ7dbH+3oS3hE 6tkevfr2+6SikuJp4rITtIXWDK3nSO/2kXbt6LqCVTFKuiszEHO1BDAep0ytIPzE 63m8INBpSm+bs4QhdQUR5f8Ab8uFh/SPozZlxq3mxMf5QARvbbWeAiMH/iTl/HD7 XlywryI9SD7fGHkdVWApCtUH6AoYv33c9jg9a/+7RngOjv3gvI0hHr4Omt0udf+8 udS0WGNjsJy9HqtIzaaRCCe4rWqsgLzi9iCFe856P+smD9g9BoH2VgePbOzeOI4r IMnEcGBExFuEpx67lDseHYqg6R79lzlE/C1SyzcCOEbvvjMUL+/nqm+AjEMa5++w wL0gyiAZrUZjFhsr4QjQESsUDqlB7K7YHfLNLxwlC8vg9/4V7StoeOWhE+YVROLz 1+MJ2Kv5wlZRN/B6wKCCRSAGnuMT02xXWxNRKfS7+sHPT8eJVWBEo6K+0WNGTkhq oFJCggBBllmlegt/IOKTe6jLzKN95UHz0NSoMoj1LIqCZOMFTPJwkV5976oPy0Ba uAoH5uJpai2yRIE15mHB23Bkc1SBE3pm7VC/4NeT4i7pyb8hnb4QwhmSD1vd7J+E ZApOSoptDWSF9al6LXzEZTjCMF85fY/JsG3+jdqY6zCacUK795gcyUZ/3al5+F4E r50a/SvSp90AxrZZcpT7 =6dZB -----END PGP SIGNATURE----- Merge tag 'iommu-fixes-v4.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull IOMMU fixes from Joerg Roedel: - another compile-fix for my header cleanup - a couple of fixes for the recently merged IOMMU probe deferal code - fixes for ACPI/IORT code necessary with IOMMU probe deferal * tag 'iommu-fixes-v4.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: arm: dma-mapping: Reset the device's dma_ops ACPI/IORT: Move the check to get iommu_ops from translated fwspec ARM: dma-mapping: Don't tear down third-party mappings ACPI/IORT: Ignore all errors except EPROBE_DEFER iommu/of: Ignore all errors except EPROBE_DEFER iommu/of: Fix check for returning EPROBE_DEFER iommu/dma: Fix function declaration
This commit is contained in:
commit
179145e631
|
@ -19,7 +19,8 @@ struct dev_archdata {
|
|||
#ifdef CONFIG_XEN
|
||||
const struct dma_map_ops *dev_dma_ops;
|
||||
#endif
|
||||
bool dma_coherent;
|
||||
unsigned int dma_coherent:1;
|
||||
unsigned int dma_ops_setup:1;
|
||||
};
|
||||
|
||||
struct omap_device;
|
||||
|
|
|
@ -2311,7 +2311,14 @@ int arm_iommu_attach_device(struct device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
|
||||
|
||||
static void __arm_iommu_detach_device(struct device *dev)
|
||||
/**
|
||||
* arm_iommu_detach_device
|
||||
* @dev: valid struct device pointer
|
||||
*
|
||||
* Detaches the provided device from a previously attached map.
|
||||
* This voids the dma operations (dma_map_ops pointer)
|
||||
*/
|
||||
void arm_iommu_detach_device(struct device *dev)
|
||||
{
|
||||
struct dma_iommu_mapping *mapping;
|
||||
|
||||
|
@ -2324,22 +2331,10 @@ static void __arm_iommu_detach_device(struct device *dev)
|
|||
iommu_detach_device(mapping->domain, dev);
|
||||
kref_put(&mapping->kref, release_iommu_mapping);
|
||||
to_dma_iommu_mapping(dev) = NULL;
|
||||
set_dma_ops(dev, NULL);
|
||||
|
||||
pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
|
||||
}
|
||||
|
||||
/**
|
||||
* arm_iommu_detach_device
|
||||
* @dev: valid struct device pointer
|
||||
*
|
||||
* Detaches the provided device from a previously attached map.
|
||||
* This voids the dma operations (dma_map_ops pointer)
|
||||
*/
|
||||
void arm_iommu_detach_device(struct device *dev)
|
||||
{
|
||||
__arm_iommu_detach_device(dev);
|
||||
set_dma_ops(dev, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
|
||||
|
||||
static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
|
||||
|
@ -2379,7 +2374,7 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
|
|||
if (!mapping)
|
||||
return;
|
||||
|
||||
__arm_iommu_detach_device(dev);
|
||||
arm_iommu_detach_device(dev);
|
||||
arm_iommu_release_mapping(mapping);
|
||||
}
|
||||
|
||||
|
@ -2430,9 +2425,13 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
|
|||
dev->dma_ops = xen_dma_ops;
|
||||
}
|
||||
#endif
|
||||
dev->archdata.dma_ops_setup = true;
|
||||
}
|
||||
|
||||
void arch_teardown_dma_ops(struct device *dev)
|
||||
{
|
||||
if (!dev->archdata.dma_ops_setup)
|
||||
return;
|
||||
|
||||
arm_teardown_iommu_dma_ops(dev);
|
||||
}
|
||||
|
|
|
@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
|
|||
int ret = -ENODEV;
|
||||
struct fwnode_handle *iort_fwnode;
|
||||
|
||||
/*
|
||||
* If we already translated the fwspec there
|
||||
* is nothing left to do, return the iommu_ops.
|
||||
*/
|
||||
ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
|
||||
if (ops)
|
||||
return ops;
|
||||
|
||||
if (node) {
|
||||
iort_fwnode = iort_get_fwnode(node);
|
||||
if (!iort_fwnode)
|
||||
|
@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
|||
u32 streamid = 0;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* If we already translated the fwspec there
|
||||
* is nothing left to do, return the iommu_ops.
|
||||
*/
|
||||
ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
|
||||
if (ops)
|
||||
return ops;
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
struct pci_bus *bus = to_pci_dev(dev)->bus;
|
||||
u32 rid;
|
||||
|
@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
|||
if (err)
|
||||
ops = ERR_PTR(err);
|
||||
|
||||
/* Ignore all other errors apart from EPROBE_DEFER */
|
||||
if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
|
||||
dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
|
||||
ops = NULL;
|
||||
}
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
|
|
|
@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
|
|||
iort_set_dma_mask(dev);
|
||||
|
||||
iommu = iort_iommu_configure(dev);
|
||||
if (IS_ERR(iommu))
|
||||
return PTR_ERR(iommu);
|
||||
if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
|
||||
/*
|
||||
|
|
|
@ -118,6 +118,7 @@ static const struct iommu_ops
|
|||
|
||||
ops = iommu_ops_from_fwnode(fwnode);
|
||||
if ((ops && !ops->of_xlate) ||
|
||||
!of_device_is_available(iommu_spec->np) ||
|
||||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
|
||||
return NULL;
|
||||
|
||||
|
@ -236,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
|
|||
ops = ERR_PTR(err);
|
||||
}
|
||||
|
||||
/* Ignore all other errors apart from EPROBE_DEFER */
|
||||
if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) {
|
||||
dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops));
|
||||
ops = NULL;
|
||||
}
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,8 +144,8 @@ int of_dma_configure(struct device *dev, struct device_node *np)
|
|||
coherent ? " " : " not ");
|
||||
|
||||
iommu = of_iommu_configure(dev, np);
|
||||
if (IS_ERR(iommu))
|
||||
return PTR_ERR(iommu);
|
||||
if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
dev_dbg(dev, "device is%sbehind an iommu\n",
|
||||
iommu ? " " : " not ");
|
||||
|
|
|
@ -78,6 +78,7 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
|
|||
|
||||
struct iommu_domain;
|
||||
struct msi_msg;
|
||||
struct device;
|
||||
|
||||
static inline int iommu_dma_init(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue