Re: [RFC PATCH v2 05/10] iommu/riscv: support GSCID and GVMA invalidation command
Andrew Jones <[email protected]>
| Newsgroups | org.infradead.lists.kvm-riscv,dev.linux.lists.iommu,org.infradead.lists.linux-riscv,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <4mcwrlk7yc4kozsqbrumf5gbknydquzwdb4g7lv6bgjk7m6ob2@alld2yusipnq> |
On Thu, May 07, 2026 at 07:37:01PM +0800, [email protected] wrote: > @@ -1212,8 +1225,15 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain, > if (!riscv_iommu_pt_supported(iommu, pt_info.fsc_iosatp_mode)) > return -ENODEV; This needs something like the below diff squashed in. Thanks, drew > > - dc.fsc = FIELD_PREP(RISCV_IOMMU_PC_FSC_MODE, pt_info.fsc_iosatp_mode) | > - FIELD_PREP(RISCV_IOMMU_PC_FSC_PPN, pt_info.ppn); > + if (domain->gscid) { > + dc.iohgatp = FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_MODE, pt_info.iohgatp_mode) | > + FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_GSCID, domain->gscid) | > + FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_PPN, pt_info.ppn); > + } else { > + dc.fsc = FIELD_PREP(RISCV_IOMMU_PC_FSC_MODE, pt_info.fsc_iosatp_mode) | > + FIELD_PREP(RISCV_IOMMU_PC_FSC_PPN, pt_info.ppn); > + } > + > dc.ta = FIELD_PREP(RISCV_IOMMU_PC_TA_PSCID, domain->pscid) | > RISCV_IOMMU_PC_TA_V; > diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c index 307baf33c646..434d2d4f26f5 100644 --- a/drivers/iommu/riscv/iommu.c +++ b/drivers/iommu/riscv/iommu.c @@ -1262,9 +1262,9 @@ static void riscv_iommu_free_paging_domain(struct iommu_domain *iommu_domain) kfree(domain); } -static bool riscv_iommu_pt_supported(struct riscv_iommu_device *iommu, int pgd_mode) +static bool riscv_iommu_fsc_supported(struct riscv_iommu_device *iommu, int mode) { - switch (pgd_mode) { + switch (mode) { case RISCV_IOMMU_DC_FSC_IOSATP_MODE_SV39: return iommu->caps & RISCV_IOMMU_CAPABILITIES_SV39; @@ -1277,6 +1277,21 @@ static bool riscv_iommu_pt_supported(struct riscv_iommu_device *iommu, int pgd_m return false; } +static bool riscv_iommu_iohgatp_supported(struct riscv_iommu_device *iommu, int mode) +{ + switch (mode) { + case RISCV_IOMMU_DC_IOHGATP_MODE_SV39X4: + return iommu->caps & RISCV_IOMMU_CAPABILITIES_SV39X4; + + case RISCV_IOMMU_DC_IOHGATP_MODE_SV48X4: + return iommu->caps & RISCV_IOMMU_CAPABILITIES_SV48X4; + + case RISCV_IOMMU_DC_IOHGATP_MODE_SV57X4: + return iommu->caps & RISCV_IOMMU_CAPABILITIES_SV57X4; + } + return false; +} + static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain, struct device *dev, struct iommu_domain *old) @@ -1294,14 +1309,17 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain, pt_iommu_riscv_64_hw_info(&domain->riscvpt, &pt_info); - if (!riscv_iommu_pt_supported(iommu, pt_info.fsc_iosatp_mode)) - return -ENODEV; - if (domain->gscid) { + if (!riscv_iommu_iohgatp_supported(iommu, pt_info.iohgatp_mode)) + return -ENODEV; + dc.iohgatp = FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_MODE, pt_info.iohgatp_mode) | FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_GSCID, domain->gscid) | FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_PPN, pt_info.ppn); } else { + if (!riscv_iommu_fsc_supported(iommu, pt_info.fsc_iosatp_mode)) + return -ENODEV; + dc.fsc = FIELD_PREP(RISCV_IOMMU_PC_FSC_MODE, pt_info.fsc_iosatp_mode) | FIELD_PREP(RISCV_IOMMU_PC_FSC_PPN, pt_info.ppn); } -- kvm-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kvm-riscv