mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge branches 'arm/renesas', 'arm/omap', 'arm/exynos', 'x86/amd', 'x86/vt-d' and 'core' into next
This commit is contained in:
commit
fedbd940d1
858 changed files with 12085 additions and 4067 deletions
|
|
@ -616,7 +616,9 @@ retry:
|
|||
address, flags);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
|
||||
printk(KERN_ERR "UNKNOWN type=0x%02x event[0]=0x%08x "
|
||||
"event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n",
|
||||
type, event[0], event[1], event[2], event[3]);
|
||||
}
|
||||
|
||||
memset(__evt, 0, 4 * sizeof(u32));
|
||||
|
|
@ -1815,7 +1817,8 @@ static bool dma_ops_domain(struct protection_domain *domain)
|
|||
return domain->flags & PD_DMA_OPS_MASK;
|
||||
}
|
||||
|
||||
static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
|
||||
static void set_dte_entry(u16 devid, struct protection_domain *domain,
|
||||
bool ats, bool ppr)
|
||||
{
|
||||
u64 pte_root = 0;
|
||||
u64 flags = 0;
|
||||
|
|
@ -1832,6 +1835,13 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
|
|||
if (ats)
|
||||
flags |= DTE_FLAG_IOTLB;
|
||||
|
||||
if (ppr) {
|
||||
struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
|
||||
|
||||
if (iommu_feature(iommu, FEATURE_EPHSUP))
|
||||
pte_root |= 1ULL << DEV_ENTRY_PPR;
|
||||
}
|
||||
|
||||
if (domain->flags & PD_IOMMUV2_MASK) {
|
||||
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
|
||||
u64 glx = domain->glx;
|
||||
|
|
@ -1894,9 +1904,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
|
|||
domain->dev_cnt += 1;
|
||||
|
||||
/* Update device table */
|
||||
set_dte_entry(dev_data->devid, domain, ats);
|
||||
set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
|
||||
if (alias != dev_data->devid)
|
||||
set_dte_entry(alias, domain, ats);
|
||||
set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
|
||||
|
||||
device_flush_dte(dev_data);
|
||||
}
|
||||
|
|
@ -2275,13 +2285,15 @@ static void update_device_table(struct protection_domain *domain)
|
|||
struct iommu_dev_data *dev_data;
|
||||
|
||||
list_for_each_entry(dev_data, &domain->dev_list, list) {
|
||||
set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
|
||||
set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
|
||||
dev_data->iommu_v2);
|
||||
|
||||
if (dev_data->devid == dev_data->alias)
|
||||
continue;
|
||||
|
||||
/* There is an alias, update device table entry for it */
|
||||
set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
|
||||
set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
|
||||
dev_data->iommu_v2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4184,7 +4196,7 @@ static void amd_ir_update_irte(struct irq_data *irqd, struct amd_iommu *iommu,
|
|||
struct irq_cfg *cfg);
|
||||
|
||||
static int irq_remapping_activate(struct irq_domain *domain,
|
||||
struct irq_data *irq_data, bool early)
|
||||
struct irq_data *irq_data, bool reserve)
|
||||
{
|
||||
struct amd_ir_data *data = irq_data->chip_data;
|
||||
struct irq_2_irte *irte_info = &data->irq_2_irte;
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
#define FEATURE_HE (1ULL<<8)
|
||||
#define FEATURE_PC (1ULL<<9)
|
||||
#define FEATURE_GAM_VAPIC (1ULL<<21)
|
||||
#define FEATURE_EPHSUP (1ULL<<50)
|
||||
|
||||
#define FEATURE_PASID_SHIFT 32
|
||||
#define FEATURE_PASID_MASK (0x1fULL << FEATURE_PASID_SHIFT)
|
||||
|
|
@ -192,6 +193,7 @@
|
|||
/* macros and definitions for device table entries */
|
||||
#define DEV_ENTRY_VALID 0x00
|
||||
#define DEV_ENTRY_TRANSLATION 0x01
|
||||
#define DEV_ENTRY_PPR 0x34
|
||||
#define DEV_ENTRY_IR 0x3d
|
||||
#define DEV_ENTRY_IW 0x3e
|
||||
#define DEV_ENTRY_NO_PAGE_FAULT 0x62
|
||||
|
|
|
|||
|
|
@ -1698,13 +1698,15 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
|
|||
domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
|
||||
domain->geometry.aperture_end = (1UL << ias) - 1;
|
||||
domain->geometry.force_aperture = true;
|
||||
smmu_domain->pgtbl_ops = pgtbl_ops;
|
||||
|
||||
ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
free_io_pgtable_ops(pgtbl_ops);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
smmu_domain->pgtbl_ops = pgtbl_ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
|
||||
|
|
@ -1731,7 +1733,7 @@ static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
|
|||
|
||||
static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
struct arm_smmu_master_data *master = fwspec->iommu_priv;
|
||||
struct arm_smmu_device *smmu = master->smmu;
|
||||
|
||||
|
|
@ -1739,6 +1741,13 @@ static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
|
|||
u32 sid = fwspec->ids[i];
|
||||
__le64 *step = arm_smmu_get_step_for_sid(smmu, sid);
|
||||
|
||||
/* Bridged PCI devices may end up with duplicated IDs */
|
||||
for (j = 0; j < i; j++)
|
||||
if (fwspec->ids[j] == sid)
|
||||
break;
|
||||
if (j < i)
|
||||
continue;
|
||||
|
||||
arm_smmu_write_strtab_ent(smmu, sid, step, &master->ste);
|
||||
}
|
||||
}
|
||||
|
|
@ -2962,7 +2971,7 @@ static struct platform_driver arm_smmu_driver = {
|
|||
};
|
||||
module_platform_driver(arm_smmu_driver);
|
||||
|
||||
IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
|
||||
IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3");
|
||||
|
||||
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
|
||||
MODULE_AUTHOR("Will Deacon <[email protected]>");
|
||||
|
|
|
|||
|
|
@ -2211,12 +2211,12 @@ static struct platform_driver arm_smmu_driver = {
|
|||
};
|
||||
module_platform_driver(arm_smmu_driver);
|
||||
|
||||
IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
|
||||
IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
|
||||
IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
|
||||
IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
|
||||
IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
|
||||
IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
|
||||
IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1");
|
||||
IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2");
|
||||
IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400");
|
||||
IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
|
||||
IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
|
||||
IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
|
||||
|
||||
MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
|
||||
MODULE_AUTHOR("Will Deacon <[email protected]>");
|
||||
|
|
|
|||
|
|
@ -1353,8 +1353,15 @@ static const struct iommu_ops exynos_iommu_ops = {
|
|||
|
||||
static int __init exynos_iommu_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
|
||||
np = of_find_matching_node(NULL, sysmmu_of_match);
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
|
||||
LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
|
||||
if (!lv2table_kmem_cache) {
|
||||
|
|
@ -1394,4 +1401,4 @@ err_reg_driver:
|
|||
}
|
||||
core_initcall(exynos_iommu_init);
|
||||
|
||||
IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu", NULL);
|
||||
IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu");
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
#define IOAPIC_RANGE_END (0xfeefffff)
|
||||
#define IOVA_START_ADDR (0x1000)
|
||||
|
||||
#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
|
||||
#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
|
||||
|
||||
#define MAX_AGAW_WIDTH 64
|
||||
#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
|
||||
|
|
@ -1601,8 +1601,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
|
|||
* flush. However, device IOTLB doesn't need to be flushed in this case.
|
||||
*/
|
||||
if (!cap_caching_mode(iommu->cap) || !map)
|
||||
iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
|
||||
addr, mask);
|
||||
iommu_flush_dev_iotlb(domain, addr, mask);
|
||||
}
|
||||
|
||||
static void iommu_flush_iova(struct iova_domain *iovad)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#define PASID_ENTRY_P BIT_ULL(0)
|
||||
#define PASID_ENTRY_FLPM_5LP BIT_ULL(9)
|
||||
#define PASID_ENTRY_SRE BIT_ULL(11)
|
||||
|
||||
static irqreturn_t prq_event_thread(int irq, void *d);
|
||||
|
||||
struct pasid_entry {
|
||||
|
|
@ -41,6 +45,14 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
|
|||
struct page *pages;
|
||||
int order;
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_GBPAGES) &&
|
||||
!cap_fl1gp_support(iommu->cap))
|
||||
return -EINVAL;
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_LA57) &&
|
||||
!cap_5lp_support(iommu->cap))
|
||||
return -EINVAL;
|
||||
|
||||
/* Start at 2 because it's defined as 2^(1+PSS) */
|
||||
iommu->pasid_max = 2 << ecap_pss(iommu->ecap);
|
||||
|
||||
|
|
@ -129,6 +141,7 @@ int intel_svm_enable_prq(struct intel_iommu *iommu)
|
|||
pr_err("IOMMU: %s: Failed to request IRQ for page request queue\n",
|
||||
iommu->name);
|
||||
dmar_free_hwirq(irq);
|
||||
iommu->pr_irq = 0;
|
||||
goto err;
|
||||
}
|
||||
dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
|
||||
|
|
@ -144,9 +157,11 @@ int intel_svm_finish_prq(struct intel_iommu *iommu)
|
|||
dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
|
||||
dmar_writeq(iommu->reg + DMAR_PQA_REG, 0ULL);
|
||||
|
||||
free_irq(iommu->pr_irq, iommu);
|
||||
dmar_free_hwirq(iommu->pr_irq);
|
||||
iommu->pr_irq = 0;
|
||||
if (iommu->pr_irq) {
|
||||
free_irq(iommu->pr_irq, iommu);
|
||||
dmar_free_hwirq(iommu->pr_irq);
|
||||
iommu->pr_irq = 0;
|
||||
}
|
||||
|
||||
free_pages((unsigned long)iommu->prq, PRQ_ORDER);
|
||||
iommu->prq = NULL;
|
||||
|
|
@ -289,6 +304,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
|
|||
struct intel_svm_dev *sdev;
|
||||
struct intel_svm *svm = NULL;
|
||||
struct mm_struct *mm = NULL;
|
||||
u64 pasid_entry_val;
|
||||
int pasid_max;
|
||||
int ret;
|
||||
|
||||
|
|
@ -395,9 +411,15 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
|
|||
kfree(sdev);
|
||||
goto out;
|
||||
}
|
||||
iommu->pasid_table[svm->pasid].val = (u64)__pa(mm->pgd) | 1;
|
||||
pasid_entry_val = (u64)__pa(mm->pgd) | PASID_ENTRY_P;
|
||||
} else
|
||||
iommu->pasid_table[svm->pasid].val = (u64)__pa(init_mm.pgd) | 1 | (1ULL << 11);
|
||||
pasid_entry_val = (u64)__pa(init_mm.pgd) |
|
||||
PASID_ENTRY_P | PASID_ENTRY_SRE;
|
||||
if (cpu_feature_enabled(X86_FEATURE_LA57))
|
||||
pasid_entry_val |= PASID_ENTRY_FLPM_5LP;
|
||||
|
||||
iommu->pasid_table[svm->pasid].val = pasid_entry_val;
|
||||
|
||||
wmb();
|
||||
/* In caching mode, we still have to flush with PASID 0 when
|
||||
* a PASID table entry becomes present. Not entirely clear
|
||||
|
|
|
|||
|
|
@ -1397,7 +1397,7 @@ static void intel_irq_remapping_free(struct irq_domain *domain,
|
|||
}
|
||||
|
||||
static int intel_irq_remapping_activate(struct irq_domain *domain,
|
||||
struct irq_data *irq_data, bool early)
|
||||
struct irq_data *irq_data, bool reserve)
|
||||
{
|
||||
intel_ir_reconfigure_irte(irq_data, true);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1303,6 +1303,9 @@ int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
|
|||
int ret;
|
||||
|
||||
group = iommu_group_get(dev);
|
||||
if (!group)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Lock the group to make sure the device-count doesn't
|
||||
* change while we are attaching
|
||||
|
|
@ -1341,6 +1344,8 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
|
|||
struct iommu_group *group;
|
||||
|
||||
group = iommu_group_get(dev);
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
mutex_lock(&group->mutex);
|
||||
if (iommu_group_device_count(group) != 1) {
|
||||
|
|
|
|||
|
|
@ -1108,18 +1108,8 @@ static void __exit ipmmu_exit(void)
|
|||
subsys_initcall(ipmmu_init);
|
||||
module_exit(ipmmu_exit);
|
||||
|
||||
#ifdef CONFIG_IOMMU_DMA
|
||||
static int __init ipmmu_vmsa_iommu_of_setup(struct device_node *np)
|
||||
{
|
||||
ipmmu_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa",
|
||||
ipmmu_vmsa_iommu_of_setup);
|
||||
IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795",
|
||||
ipmmu_vmsa_iommu_of_setup);
|
||||
#endif
|
||||
IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa");
|
||||
IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795");
|
||||
|
||||
MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
|
||||
MODULE_AUTHOR("Laurent Pinchart <[email protected]>");
|
||||
|
|
|
|||
|
|
@ -823,6 +823,8 @@ static int msm_iommu_probe(struct platform_device *pdev)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
|
||||
|
||||
pr_info("device mapped at %p, irq %d with %d ctx banks\n",
|
||||
iommu->base, iommu->irq, iommu->ncb);
|
||||
|
||||
|
|
@ -875,19 +877,7 @@ static void __exit msm_iommu_driver_exit(void)
|
|||
subsys_initcall(msm_iommu_driver_init);
|
||||
module_exit(msm_iommu_driver_exit);
|
||||
|
||||
static int __init msm_iommu_init(void)
|
||||
{
|
||||
bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init msm_iommu_of_setup(struct device_node *np)
|
||||
{
|
||||
msm_iommu_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", msm_iommu_of_setup);
|
||||
IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu");
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Stepan Moskovchenko <[email protected]>");
|
||||
|
|
|
|||
|
|
@ -231,19 +231,3 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
|
|||
|
||||
return ops;
|
||||
}
|
||||
|
||||
static int __init of_iommu_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
const struct of_device_id *match, *matches = &__iommu_of_table;
|
||||
|
||||
for_each_matching_node_and_match(np, matches, &match) {
|
||||
const of_iommu_init_fn init_fn = match->data;
|
||||
|
||||
if (init_fn && init_fn(np))
|
||||
pr_err("Failed to initialise IOMMU %pOF\n", np);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall_sync(of_iommu_init);
|
||||
|
|
|
|||
|
|
@ -274,8 +274,8 @@ void omap_iommu_debugfs_add(struct omap_iommu *obj)
|
|||
if (!obj->debug_dir)
|
||||
return;
|
||||
|
||||
d = debugfs_create_u8("nr_tlb_entries", 0400, obj->debug_dir,
|
||||
(u8 *)&obj->nr_tlb_entries);
|
||||
d = debugfs_create_u32("nr_tlb_entries", 0400, obj->debug_dir,
|
||||
&obj->nr_tlb_entries);
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -947,7 +947,7 @@ static void __exit qcom_iommu_exit(void)
|
|||
module_init(qcom_iommu_init);
|
||||
module_exit(qcom_iommu_exit);
|
||||
|
||||
IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1", NULL);
|
||||
IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1");
|
||||
|
||||
MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
|||
Loading…
Reference in a new issue