mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-31 12:10:52 -04:00
IOMMU Updates for Linux v4.12
This includes: * Some code optimizations for the Intel VT-d driver * Code to switch off a previously enabled Intel IOMMU * Support for 'struct iommu_device' for OMAP, Rockchip and Mediatek IOMMUs * Some header optimizations for IOMMU core code headers and a few fixes that became necessary in other parts of the kernel because of that * ACPI/IORT updates and fixes * Some Exynos IOMMU optimizations * Code updates for the IOMMU dma-api code to bring it closer to use per-cpu iova caches * New command-line option to set default domain type allocated by the iommu core code * Another command line option to allow the Intel IOMMU switched off in a tboot environment * ARM/SMMU: TLB sync optimisations for SMMUv2, Support for using an IDENTITY domain in conjunction with DMA ops, Support for SMR masking, Support for 16-bit ASIDs (was previously broken) * Various other small fixes and improvements -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJZEY4XAAoJECvwRC2XARrjth0QAKV56zjnFclv39aDo6eCq9CT 51+XT4bPY5VKQ2+Jx76TBNObHmGK+8KEMHfT9khpWJtFCDyy25SGckLry1nYqmZs tSTsbj4sOeCyKzOLITlRN9/OzKXkjKAxYuq+sQZZFDFYf3kCM/eag0dGAU6aVLNp tkIal3CSpGjCQ9M5JohrtQ1mwiGqCIkMIgvnBjRw+bfpLnQNG+VL6VU2G3RAkV2b 5Vbdoy+P7ZQnJSZr/bibYL2BaQs2diR4gOppT5YbsfniMq4QYSjheu1xBboGX8b7 sx8yuPi4370irSan0BDvlvdQdjBKIRiDjfGEKDhRwPhtvN6JREGakhEOC8MySQ37 mP96B72Lmd+a7DEl5udOL7tQILA0DcUCX0aOyF714khnZuFU5tVlCotb/36xeJ+T FPc3RbEVQ90m8dYU6MNJ+ahtb/ZapxGTRfisIigB6wlnZa0Evabp9EJSce6oJMkm whbBhDubeEU18n9XAaofMbu+P2LAzq8cxiRMlsDvT4mIy7jO86jjCmhpu1Tfn2GY 4wrEQZdWOMvhUsIhObXA0aC3BzC506uvnKPW3qy041RaxBuelWiBi29qzYbhxzkr DLDpWbUZNYPyFJjttpavyQb2/XRduBTJdVP1pQpkJNDsW5jLiBkpSqm9xNADapRY vLSYRX0JCIquaD+PAuxn =3aE8 -----END PGP SIGNATURE----- Merge tag 'iommu-updates-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull IOMMU updates from Joerg Roedel: - code optimizations for the Intel VT-d driver - ability to switch off a previously enabled Intel IOMMU - support for 'struct iommu_device' for OMAP, Rockchip and Mediatek IOMMUs - header optimizations for IOMMU core code headers and a few fixes that became necessary in other parts of the kernel because of that - ACPI/IORT updates and fixes - Exynos IOMMU optimizations - updates for the IOMMU dma-api code to bring it closer to use per-cpu iova caches - new command-line option to set default domain type allocated by the iommu core code - another command line option to allow the Intel IOMMU switched off in a tboot environment - ARM/SMMU: TLB sync optimisations for SMMUv2, Support for using an IDENTITY domain in conjunction with DMA ops, Support for SMR masking, Support for 16-bit ASIDs (was previously broken) - various other small fixes and improvements * tag 'iommu-updates-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (63 commits) soc/qbman: Move dma-mapping.h include to qman_priv.h soc/qbman: Fix implicit header dependency now causing build fails iommu: Remove trace-events include from iommu.h iommu: Remove pci.h include from trace/events/iommu.h arm: dma-mapping: Don't override dma_ops in arch_setup_dma_ops() ACPI/IORT: Fix CONFIG_IOMMU_API dependency iommu/vt-d: Don't print the failure message when booting non-kdump kernel iommu: Move report_iommu_fault() to iommu.c iommu: Include device.h in iommu.h x86, iommu/vt-d: Add an option to disable Intel IOMMU force on iommu/arm-smmu: Return IOVA in iova_to_phys when SMMU is bypassed iommu/arm-smmu: Correct sid to mask iommu/amd: Fix incorrect error handling in amd_iommu_bind_pasid() iommu: Make iommu_bus_notifier return NOTIFY_DONE rather than error code omap3isp: Remove iommu_group related code iommu/omap: Add iommu-group support iommu/omap: Make use of 'struct iommu_device' iommu/omap: Store iommu_dev pointer in arch_data iommu/omap: Move data structures to omap-iommu.h iommu/omap: Drop legacy-style device support ...
This commit is contained in:
commit
28b47809b2
48 changed files with 1188 additions and 765 deletions
|
|
@ -618,6 +618,46 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline bool iort_iommu_driver_enabled(u8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case ACPI_IORT_NODE_SMMU_V3:
|
||||
return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
|
||||
case ACPI_IORT_NODE_SMMU:
|
||||
return IS_BUILTIN(CONFIG_ARM_SMMU);
|
||||
default:
|
||||
pr_warn("IORT node type %u does not describe an SMMU\n", type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IOMMU_API
|
||||
static inline
|
||||
const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec)
|
||||
{
|
||||
return (fwspec && fwspec->ops) ? fwspec->ops : NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!IS_ERR_OR_NULL(ops) && ops->add_device && dev->bus &&
|
||||
!dev->iommu_group)
|
||||
err = ops->add_device(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec)
|
||||
{ return NULL; }
|
||||
static inline
|
||||
int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
|
||||
struct acpi_iort_node *node,
|
||||
u32 streamid)
|
||||
|
|
@ -626,14 +666,31 @@ 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)
|
||||
return NULL;
|
||||
|
||||
ops = iommu_ops_from_fwnode(iort_fwnode);
|
||||
/*
|
||||
* If the ops look-up fails, this means that either
|
||||
* the SMMU drivers have not been probed yet or that
|
||||
* the SMMU drivers are not built in the kernel;
|
||||
* Depending on whether the SMMU drivers are built-in
|
||||
* in the kernel or not, defer the IOMMU configuration
|
||||
* or just abort it.
|
||||
*/
|
||||
if (!ops)
|
||||
return NULL;
|
||||
return iort_iommu_driver_enabled(node->type) ?
|
||||
ERR_PTR(-EPROBE_DEFER) : NULL;
|
||||
|
||||
ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
|
||||
}
|
||||
|
|
@ -676,6 +733,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
|||
struct acpi_iort_node *node, *parent;
|
||||
const struct iommu_ops *ops = NULL;
|
||||
u32 streamid = 0;
|
||||
int err;
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
struct pci_bus *bus = to_pci_dev(dev)->bus;
|
||||
|
|
@ -707,6 +765,8 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
|||
|
||||
while (parent) {
|
||||
ops = iort_iommu_xlate(dev, parent, streamid);
|
||||
if (IS_ERR_OR_NULL(ops))
|
||||
return ops;
|
||||
|
||||
parent = iort_node_map_platform_id(node, &streamid,
|
||||
IORT_IOMMU_TYPE,
|
||||
|
|
@ -714,6 +774,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have reason to believe the IOMMU driver missed the initial
|
||||
* add_device callback for dev, replay it to get things in order.
|
||||
*/
|
||||
err = iort_add_device_replay(ops, dev);
|
||||
if (err)
|
||||
ops = ERR_PTR(err);
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
|
|
@ -1052,6 +1120,4 @@ void __init acpi_iort_init(void)
|
|||
}
|
||||
|
||||
iort_init_platform_devices();
|
||||
|
||||
acpi_probe_device_table(iort);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
struct list_head *physnode_list;
|
||||
unsigned int node_id;
|
||||
int retval = -EINVAL;
|
||||
enum dev_dma_attr attr;
|
||||
|
||||
if (has_acpi_companion(dev)) {
|
||||
if (acpi_dev) {
|
||||
|
|
@ -236,10 +235,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
if (!has_acpi_companion(dev))
|
||||
ACPI_COMPANION_SET(dev, acpi_dev);
|
||||
|
||||
attr = acpi_get_dma_attr(acpi_dev);
|
||||
if (attr != DEV_DMA_NOT_SUPPORTED)
|
||||
acpi_dma_configure(dev, attr);
|
||||
|
||||
acpi_physnode_link_name(physical_node_name, node_id);
|
||||
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
|
||||
physical_node_name);
|
||||
|
|
|
|||
|
|
@ -1363,20 +1363,25 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
|
|||
* @dev: The pointer to the device
|
||||
* @attr: device dma attributes
|
||||
*/
|
||||
void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
|
||||
int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
|
||||
{
|
||||
const struct iommu_ops *iommu;
|
||||
u64 size;
|
||||
|
||||
iort_set_dma_mask(dev);
|
||||
|
||||
iommu = iort_iommu_configure(dev);
|
||||
if (IS_ERR(iommu))
|
||||
return PTR_ERR(iommu);
|
||||
|
||||
size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
|
||||
/*
|
||||
* Assume dma valid range starts at 0 and covers the whole
|
||||
* coherent_dma_mask.
|
||||
*/
|
||||
arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
|
||||
attr == DEV_DMA_COHERENT);
|
||||
arch_setup_dma_ops(dev, 0, size, iommu, attr == DEV_DMA_COHERENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dma_configure);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue