Merge "iommu: arm-smmu: Set context bank page table coherency"
This commit is contained in:
commit
8cd28a094d
1 changed files with 43 additions and 1 deletions
|
@ -1723,6 +1723,17 @@ static int arm_smmu_restore_sec_cfg(struct arm_smmu_device *smmu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool is_iommu_pt_coherent(struct arm_smmu_domain *smmu_domain)
|
||||
{
|
||||
if (smmu_domain->attributes &
|
||||
(1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT))
|
||||
return true;
|
||||
else if (smmu_domain->smmu && smmu_domain->smmu->dev)
|
||||
return smmu_domain->smmu->dev->archdata.dma_coherent;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static int arm_smmu_init_domain_context(struct iommu_domain *domain,
|
||||
struct arm_smmu_device *smmu,
|
||||
struct arm_smmu_master_cfg *master_cfg)
|
||||
|
@ -1734,6 +1745,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
|
|||
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
|
||||
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
|
||||
bool is_fast = smmu_domain->attributes & (1 << DOMAIN_ATTR_FAST);
|
||||
unsigned long quirks = 0;
|
||||
|
||||
if (smmu_domain->smmu)
|
||||
goto out;
|
||||
|
@ -1810,8 +1822,12 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
|
|||
|
||||
smmu_domain->smmu = smmu;
|
||||
|
||||
if (is_iommu_pt_coherent(smmu_domain))
|
||||
quirks |= IO_PGTABLE_QUIRK_PAGE_TABLE_COHERENT;
|
||||
|
||||
if (arm_smmu_is_slave_side_secure(smmu_domain)) {
|
||||
smmu_domain->pgtbl_cfg = (struct io_pgtable_cfg) {
|
||||
.quirks = quirks,
|
||||
.pgsize_bitmap = arm_smmu_ops.pgsize_bitmap,
|
||||
.arm_msm_secure_cfg = {
|
||||
.sec_id = smmu->sec_id,
|
||||
|
@ -1822,6 +1838,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
|
|||
fmt = ARM_MSM_SECURE;
|
||||
} else {
|
||||
smmu_domain->pgtbl_cfg = (struct io_pgtable_cfg) {
|
||||
.quirks = quirks,
|
||||
.pgsize_bitmap = arm_smmu_ops.pgsize_bitmap,
|
||||
.ias = ias,
|
||||
.oas = oas,
|
||||
|
@ -3115,7 +3132,12 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
|
|||
case DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT:
|
||||
if (!smmu_domain->smmu)
|
||||
return -ENODEV;
|
||||
*((int *)data) = smmu_domain->smmu->dev->archdata.dma_coherent;
|
||||
*((int *)data) = is_iommu_pt_coherent(smmu_domain);
|
||||
ret = 0;
|
||||
break;
|
||||
case DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT:
|
||||
*((int *)data) = !!(smmu_domain->attributes
|
||||
& (1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT));
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -3241,6 +3263,26 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT: {
|
||||
int force_coherent = *((int *)data);
|
||||
|
||||
if (smmu_domain->smmu != NULL) {
|
||||
dev_err(smmu_domain->smmu->dev,
|
||||
"cannot change force coherent attribute while attached\n");
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (force_coherent)
|
||||
smmu_domain->attributes |=
|
||||
1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT;
|
||||
else
|
||||
smmu_domain->attributes &=
|
||||
~(1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT);
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue