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:
Коммит
179145e631
|
@ -19,7 +19,8 @@ struct dev_archdata {
|
||||||
#ifdef CONFIG_XEN
|
#ifdef CONFIG_XEN
|
||||||
const struct dma_map_ops *dev_dma_ops;
|
const struct dma_map_ops *dev_dma_ops;
|
||||||
#endif
|
#endif
|
||||||
bool dma_coherent;
|
unsigned int dma_coherent:1;
|
||||||
|
unsigned int dma_ops_setup:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct omap_device;
|
struct omap_device;
|
||||||
|
|
|
@ -2311,7 +2311,14 @@ int arm_iommu_attach_device(struct device *dev,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
|
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;
|
struct dma_iommu_mapping *mapping;
|
||||||
|
|
||||||
|
@ -2324,22 +2331,10 @@ static void __arm_iommu_detach_device(struct device *dev)
|
||||||
iommu_detach_device(mapping->domain, dev);
|
iommu_detach_device(mapping->domain, dev);
|
||||||
kref_put(&mapping->kref, release_iommu_mapping);
|
kref_put(&mapping->kref, release_iommu_mapping);
|
||||||
to_dma_iommu_mapping(dev) = NULL;
|
to_dma_iommu_mapping(dev) = NULL;
|
||||||
|
set_dma_ops(dev, NULL);
|
||||||
|
|
||||||
pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
|
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);
|
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
|
||||||
|
|
||||||
static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
|
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)
|
if (!mapping)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__arm_iommu_detach_device(dev);
|
arm_iommu_detach_device(dev);
|
||||||
arm_iommu_release_mapping(mapping);
|
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;
|
dev->dma_ops = xen_dma_ops;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
dev->archdata.dma_ops_setup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_teardown_dma_ops(struct device *dev)
|
void arch_teardown_dma_ops(struct device *dev)
|
||||||
{
|
{
|
||||||
|
if (!dev->archdata.dma_ops_setup)
|
||||||
|
return;
|
||||||
|
|
||||||
arm_teardown_iommu_dma_ops(dev);
|
arm_teardown_iommu_dma_ops(dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
struct fwnode_handle *iort_fwnode;
|
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) {
|
if (node) {
|
||||||
iort_fwnode = iort_get_fwnode(node);
|
iort_fwnode = iort_get_fwnode(node);
|
||||||
if (!iort_fwnode)
|
if (!iort_fwnode)
|
||||||
|
@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
||||||
u32 streamid = 0;
|
u32 streamid = 0;
|
||||||
int err;
|
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)) {
|
if (dev_is_pci(dev)) {
|
||||||
struct pci_bus *bus = to_pci_dev(dev)->bus;
|
struct pci_bus *bus = to_pci_dev(dev)->bus;
|
||||||
u32 rid;
|
u32 rid;
|
||||||
|
@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
||||||
if (err)
|
if (err)
|
||||||
ops = ERR_PTR(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;
|
return ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
|
||||||
iort_set_dma_mask(dev);
|
iort_set_dma_mask(dev);
|
||||||
|
|
||||||
iommu = iort_iommu_configure(dev);
|
iommu = iort_iommu_configure(dev);
|
||||||
if (IS_ERR(iommu))
|
if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
|
||||||
return PTR_ERR(iommu);
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
|
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);
|
ops = iommu_ops_from_fwnode(fwnode);
|
||||||
if ((ops && !ops->of_xlate) ||
|
if ((ops && !ops->of_xlate) ||
|
||||||
|
!of_device_is_available(iommu_spec->np) ||
|
||||||
(!ops && !of_iommu_driver_present(iommu_spec->np)))
|
(!ops && !of_iommu_driver_present(iommu_spec->np)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -236,6 +237,12 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
|
||||||
ops = ERR_PTR(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;
|
return ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,8 +144,8 @@ int of_dma_configure(struct device *dev, struct device_node *np)
|
||||||
coherent ? " " : " not ");
|
coherent ? " " : " not ");
|
||||||
|
|
||||||
iommu = of_iommu_configure(dev, np);
|
iommu = of_iommu_configure(dev, np);
|
||||||
if (IS_ERR(iommu))
|
if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
|
||||||
return PTR_ERR(iommu);
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
dev_dbg(dev, "device is%sbehind an iommu\n",
|
dev_dbg(dev, "device is%sbehind an iommu\n",
|
||||||
iommu ? " " : " not ");
|
iommu ? " " : " not ");
|
||||||
|
|
|
@ -78,6 +78,7 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
|
||||||
|
|
||||||
struct iommu_domain;
|
struct iommu_domain;
|
||||||
struct msi_msg;
|
struct msi_msg;
|
||||||
|
struct device;
|
||||||
|
|
||||||
static inline int iommu_dma_init(void)
|
static inline int iommu_dma_init(void)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче