mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-11 21:14:07 +08:00
Merge branch 'for-joerg/arm-smmu/fixes' into for-joerg/arm-smmu/updates
Merge in ARM SMMU fixes to avoid conflicts in the ARM io-pgtable code. * for-joerg/arm-smmu/fixes: iommu/io-pgtable-arm: Support all Mali configurations iommu/io-pgtable-arm: Correct Mali attributes iommu/arm-smmu: Free context bitmap in the err path of arm_smmu_init_domain_context
This commit is contained in:
commit
db22a9de7a
@ -828,6 +828,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
|
||||
return 0;
|
||||
|
||||
out_clear_smmu:
|
||||
__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
|
||||
smmu_domain->smmu = NULL;
|
||||
out_unlock:
|
||||
mutex_unlock(&smmu_domain->init_mutex);
|
||||
|
@ -166,6 +166,9 @@
|
||||
#define ARM_MALI_LPAE_TTBR_READ_INNER BIT(2)
|
||||
#define ARM_MALI_LPAE_TTBR_SHARE_OUTER BIT(4)
|
||||
|
||||
#define ARM_MALI_LPAE_MEMATTR_IMP_DEF 0x88ULL
|
||||
#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL
|
||||
|
||||
/* IOPTE accessors */
|
||||
#define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
|
||||
|
||||
@ -1015,27 +1018,56 @@ arm_32_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
|
||||
static struct io_pgtable *
|
||||
arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
|
||||
{
|
||||
struct io_pgtable *iop;
|
||||
struct arm_lpae_io_pgtable *data;
|
||||
|
||||
if (cfg->ias != 48 || cfg->oas > 40)
|
||||
/* No quirks for Mali (hopefully) */
|
||||
if (cfg->quirks)
|
||||
return NULL;
|
||||
|
||||
if (cfg->ias > 48 || cfg->oas > 40)
|
||||
return NULL;
|
||||
|
||||
cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G);
|
||||
iop = arm_64_lpae_alloc_pgtable_s1(cfg, cookie);
|
||||
if (iop) {
|
||||
u64 mair, ttbr;
|
||||
|
||||
/* Copy values as union fields overlap */
|
||||
mair = cfg->arm_lpae_s1_cfg.mair[0];
|
||||
ttbr = cfg->arm_lpae_s1_cfg.ttbr[0];
|
||||
data = arm_lpae_alloc_pgtable(cfg);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
cfg->arm_mali_lpae_cfg.memattr = mair;
|
||||
cfg->arm_mali_lpae_cfg.transtab = ttbr |
|
||||
/* Mali seems to need a full 4-level table regardless of IAS */
|
||||
if (data->levels < ARM_LPAE_MAX_LEVELS) {
|
||||
data->levels = ARM_LPAE_MAX_LEVELS;
|
||||
data->pgd_size = sizeof(arm_lpae_iopte);
|
||||
}
|
||||
/*
|
||||
* MEMATTR: Mali has no actual notion of a non-cacheable type, so the
|
||||
* best we can do is mimic the out-of-tree driver and hope that the
|
||||
* "implementation-defined caching policy" is good enough. Similarly,
|
||||
* we'll use it for the sake of a valid attribute for our 'device'
|
||||
* index, although callers should never request that in practice.
|
||||
*/
|
||||
cfg->arm_mali_lpae_cfg.memattr =
|
||||
(ARM_MALI_LPAE_MEMATTR_IMP_DEF
|
||||
<< ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_NC)) |
|
||||
(ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC
|
||||
<< ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
|
||||
(ARM_MALI_LPAE_MEMATTR_IMP_DEF
|
||||
<< ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV));
|
||||
|
||||
data->pgd = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg);
|
||||
if (!data->pgd)
|
||||
goto out_free_data;
|
||||
|
||||
/* Ensure the empty pgd is visible before TRANSTAB can be written */
|
||||
wmb();
|
||||
|
||||
cfg->arm_mali_lpae_cfg.transtab = virt_to_phys(data->pgd) |
|
||||
ARM_MALI_LPAE_TTBR_READ_INNER |
|
||||
ARM_MALI_LPAE_TTBR_ADRMODE_TABLE;
|
||||
}
|
||||
return &data->iop;
|
||||
|
||||
return iop;
|
||||
out_free_data:
|
||||
kfree(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {
|
||||
|
Loading…
Reference in New Issue
Block a user