Hi Keqian, On 2/2/21 9:03 AM, Keqian Zhu wrote: > Hi Eric, > > On 2020/11/18 19:21, Eric Auger wrote: >> On attach_pasid_table() we program STE S1 related info set >> by the guest into the actual physical STEs. At minimum >> we need to program the context descriptor GPA and compute >> whether the stage1 is translated/bypassed or aborted. >> >> Signed-off-by: Eric Auger <eric.auger@xxxxxxxxxx> >> >> --- >> v7 -> v8: >> - remove smmu->features check, now done on domain finalize >> >> v6 -> v7: >> - check versions and comment the fact we don't need to take >> into account s1dss and s1fmt >> v3 -> v4: >> - adapt to changes in iommu_pasid_table_config >> - different programming convention at s1_cfg/s2_cfg/ste.abort >> >> v2 -> v3: >> - callback now is named set_pasid_table and struct fields >> are laid out differently. >> >> v1 -> v2: >> - invalidate the STE before changing them >> - hold init_mutex >> - handle new fields >> --- >> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 89 +++++++++++++++++++++ >> 1 file changed, 89 insertions(+) >> >> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c >> index 412ea1bafa50..805acdc18a3a 100644 >> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c >> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c >> @@ -2661,6 +2661,93 @@ static void arm_smmu_get_resv_regions(struct device *dev, >> iommu_dma_get_resv_regions(dev, head); >> } >> >> +static int arm_smmu_attach_pasid_table(struct iommu_domain *domain, >> + struct iommu_pasid_table_config *cfg) >> +{ >> + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); >> + struct arm_smmu_master *master; >> + struct arm_smmu_device *smmu; >> + unsigned long flags; >> + int ret = -EINVAL; >> + >> + if (cfg->format != IOMMU_PASID_FORMAT_SMMUV3) >> + return -EINVAL; >> + >> + if (cfg->version != PASID_TABLE_CFG_VERSION_1 || >> + cfg->vendor_data.smmuv3.version != PASID_TABLE_SMMUV3_CFG_VERSION_1) >> + return -EINVAL; >> + >> + mutex_lock(&smmu_domain->init_mutex); >> + >> + smmu = smmu_domain->smmu; >> + >> + if (!smmu) >> + goto out; >> + >> + if (smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) >> + goto out; >> + >> + switch (cfg->config) { >> + case IOMMU_PASID_CONFIG_ABORT: >> + smmu_domain->s1_cfg.set = false; >> + smmu_domain->abort = true; >> + break; >> + case IOMMU_PASID_CONFIG_BYPASS: >> + smmu_domain->s1_cfg.set = false; >> + smmu_domain->abort = false; > I didn't test it, but it seems that this will cause BUG() in arm_smmu_write_strtab_ent(). > At the line "BUG_ON(ste_live && !nested);". Maybe I miss something? No you are fully correct. Shammeer hit the BUG_ON() when booting the guest with iommu.passthrough = 1. So I removed the BUG_ON(). The legacy BUG_ON(ste_live) still is there under the form of BUG_ON(s1_live). Thanks! Eric > >> + break; >> + case IOMMU_PASID_CONFIG_TRANSLATE: >> + /* we do not support S1 <-> S1 transitions */ >> + if (smmu_domain->s1_cfg.set) >> + goto out; >> + >> + /* >> + * we currently support a single CD so s1fmt and s1dss >> + * fields are also ignored >> + */ >> + if (cfg->pasid_bits) >> + goto out; >> + >> + smmu_domain->s1_cfg.cdcfg.cdtab_dma = cfg->base_ptr; >> + smmu_domain->s1_cfg.set = true; >> + smmu_domain->abort = false; >> + break; >> + default: >> + goto out; >> + } >> + spin_lock_irqsave(&smmu_domain->devices_lock, flags); >> + list_for_each_entry(master, &smmu_domain->devices, domain_head) >> + arm_smmu_install_ste_for_dev(master); >> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); >> + ret = 0; >> +out: >> + mutex_unlock(&smmu_domain->init_mutex); >> + return ret; >> +} >> + > [...] > > Thanks, > Keqian > _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm