Loading drivers/iommu/arm-smmu.c +41 −13 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ enum arm_smmu_s2cr_privcfg { #define SCTLR_S1_ASIDPNE (1 << 12) #define SCTLR_CFCFG (1 << 7) #define SCTLR_HUPCF (1 << 8) #define SCTLR_CFIE (1 << 6) #define SCTLR_CFRE (1 << 5) #define SCTLR_E (1 << 4) Loading Loading @@ -1453,6 +1454,11 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, /* SCTLR */ reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE; if (smmu_domain->attributes & (1 << DOMAIN_ATTR_CB_STALL_DISABLE)) { reg &= ~SCTLR_CFCFG; reg |= SCTLR_HUPCF; } if ((!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) && !(smmu_domain->attributes & (1 << DOMAIN_ATTR_EARLY_MAP))) || !stage1) Loading Loading @@ -2580,19 +2586,23 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); int ret = 0; mutex_lock(&smmu_domain->init_mutex); switch (attr) { case DOMAIN_ATTR_NESTING: *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); return 0; ret = 0; break; case DOMAIN_ATTR_PT_BASE_ADDR: *((phys_addr_t *)data) = smmu_domain->pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0]; return 0; ret = 0; break; case DOMAIN_ATTR_CONTEXT_BANK: /* context bank index isn't valid until we are attached */ if (smmu_domain->smmu == NULL) return -ENODEV; if (smmu_domain->smmu == NULL) { ret = -ENODEV; break; } *((unsigned int *) data) = smmu_domain->cfg.cbndx; ret = 0; break; Loading @@ -2600,9 +2610,10 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, u64 val; struct arm_smmu_device *smmu = smmu_domain->smmu; /* not valid until we are attached */ if (smmu == NULL) return -ENODEV; if (smmu == NULL) { ret = -ENODEV; break; } val = smmu_domain->pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0]; if (smmu_domain->cfg.cbar != CBAR_TYPE_S2_TRANS) val |= (u64)ARM_SMMU_CB_ASID(smmu, &smmu_domain->cfg) Loading @@ -2613,8 +2624,10 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, } case DOMAIN_ATTR_CONTEXTIDR: /* not valid until attached */ if (smmu_domain->smmu == NULL) return -ENODEV; if (smmu_domain->smmu == NULL) { ret = -ENODEV; break; } *((u32 *)data) = smmu_domain->cfg.procid; ret = 0; break; Loading Loading @@ -2668,8 +2681,10 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, ret = 0; break; case DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT: if (!smmu_domain->smmu) return -ENODEV; if (!smmu_domain->smmu) { ret = -ENODEV; break; } *((int *)data) = is_iommu_pt_coherent(smmu_domain); ret = 0; break; Loading @@ -2678,9 +2693,16 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, & (1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT)); ret = 0; break; case DOMAIN_ATTR_CB_STALL_DISABLE: *((int *)data) = !!(smmu_domain->attributes & (1 << DOMAIN_ATTR_CB_STALL_DISABLE)); ret = 0; break; default: return -ENODEV; ret = -ENODEV; break; } mutex_unlock(&smmu_domain->init_mutex); return ret; } Loading Loading @@ -2855,6 +2877,12 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, break; } case DOMAIN_ATTR_CB_STALL_DISABLE: if (*((int *)data)) smmu_domain->attributes |= 1 << DOMAIN_ATTR_CB_STALL_DISABLE; ret = 0; break; default: ret = -ENODEV; } Loading drivers/iommu/iommu-debug.c +2 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ static const char *iommu_debug_attr_to_string(enum iommu_attr attr) return "DOMAIN_ATTR_FAST"; case DOMAIN_ATTR_EARLY_MAP: return "DOMAIN_ATTR_EARLY_MAP"; case DOMAIN_ATTR_CB_STALL_DISABLE: return "DOMAIN_ATTR_CB_STALL_DISABLE"; default: return "Unknown attr!"; } Loading include/linux/iommu.h +1 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,7 @@ enum iommu_attr { DOMAIN_ATTR_EARLY_MAP, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT, DOMAIN_ATTR_CB_STALL_DISABLE, DOMAIN_ATTR_MAX, }; Loading Loading
drivers/iommu/arm-smmu.c +41 −13 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ enum arm_smmu_s2cr_privcfg { #define SCTLR_S1_ASIDPNE (1 << 12) #define SCTLR_CFCFG (1 << 7) #define SCTLR_HUPCF (1 << 8) #define SCTLR_CFIE (1 << 6) #define SCTLR_CFRE (1 << 5) #define SCTLR_E (1 << 4) Loading Loading @@ -1453,6 +1454,11 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, /* SCTLR */ reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE; if (smmu_domain->attributes & (1 << DOMAIN_ATTR_CB_STALL_DISABLE)) { reg &= ~SCTLR_CFCFG; reg |= SCTLR_HUPCF; } if ((!(smmu_domain->attributes & (1 << DOMAIN_ATTR_S1_BYPASS)) && !(smmu_domain->attributes & (1 << DOMAIN_ATTR_EARLY_MAP))) || !stage1) Loading Loading @@ -2580,19 +2586,23 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); int ret = 0; mutex_lock(&smmu_domain->init_mutex); switch (attr) { case DOMAIN_ATTR_NESTING: *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); return 0; ret = 0; break; case DOMAIN_ATTR_PT_BASE_ADDR: *((phys_addr_t *)data) = smmu_domain->pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0]; return 0; ret = 0; break; case DOMAIN_ATTR_CONTEXT_BANK: /* context bank index isn't valid until we are attached */ if (smmu_domain->smmu == NULL) return -ENODEV; if (smmu_domain->smmu == NULL) { ret = -ENODEV; break; } *((unsigned int *) data) = smmu_domain->cfg.cbndx; ret = 0; break; Loading @@ -2600,9 +2610,10 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, u64 val; struct arm_smmu_device *smmu = smmu_domain->smmu; /* not valid until we are attached */ if (smmu == NULL) return -ENODEV; if (smmu == NULL) { ret = -ENODEV; break; } val = smmu_domain->pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0]; if (smmu_domain->cfg.cbar != CBAR_TYPE_S2_TRANS) val |= (u64)ARM_SMMU_CB_ASID(smmu, &smmu_domain->cfg) Loading @@ -2613,8 +2624,10 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, } case DOMAIN_ATTR_CONTEXTIDR: /* not valid until attached */ if (smmu_domain->smmu == NULL) return -ENODEV; if (smmu_domain->smmu == NULL) { ret = -ENODEV; break; } *((u32 *)data) = smmu_domain->cfg.procid; ret = 0; break; Loading Loading @@ -2668,8 +2681,10 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, ret = 0; break; case DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT: if (!smmu_domain->smmu) return -ENODEV; if (!smmu_domain->smmu) { ret = -ENODEV; break; } *((int *)data) = is_iommu_pt_coherent(smmu_domain); ret = 0; break; Loading @@ -2678,9 +2693,16 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, & (1 << DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT)); ret = 0; break; case DOMAIN_ATTR_CB_STALL_DISABLE: *((int *)data) = !!(smmu_domain->attributes & (1 << DOMAIN_ATTR_CB_STALL_DISABLE)); ret = 0; break; default: return -ENODEV; ret = -ENODEV; break; } mutex_unlock(&smmu_domain->init_mutex); return ret; } Loading Loading @@ -2855,6 +2877,12 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, break; } case DOMAIN_ATTR_CB_STALL_DISABLE: if (*((int *)data)) smmu_domain->attributes |= 1 << DOMAIN_ATTR_CB_STALL_DISABLE; ret = 0; break; default: ret = -ENODEV; } Loading
drivers/iommu/iommu-debug.c +2 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ static const char *iommu_debug_attr_to_string(enum iommu_attr attr) return "DOMAIN_ATTR_FAST"; case DOMAIN_ATTR_EARLY_MAP: return "DOMAIN_ATTR_EARLY_MAP"; case DOMAIN_ATTR_CB_STALL_DISABLE: return "DOMAIN_ATTR_CB_STALL_DISABLE"; default: return "Unknown attr!"; } Loading
include/linux/iommu.h +1 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,7 @@ enum iommu_attr { DOMAIN_ATTR_EARLY_MAP, DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT, DOMAIN_ATTR_CB_STALL_DISABLE, DOMAIN_ATTR_MAX, }; Loading